Skip to content

Instantly share code, notes, and snippets.

@Jasemalsadi
Created October 10, 2023 19:36
Show Gist options
  • Select an option

  • Save Jasemalsadi/be029db1fdd7a6231a324ba7044f66e1 to your computer and use it in GitHub Desktop.

Select an option

Save Jasemalsadi/be029db1fdd7a6231a324ba7044f66e1 to your computer and use it in GitHub Desktop.
Windbg JS function to break when any cmp or test instruction comparing our input buffer (e.g. 4141)
function find_cmp_use_shellcode(patternsArg) {
/*
.scriptrun c:\scripts\debug.js
bp 0056C4B6
bp 0056c850
g
dx .State.Scripts.debug.Contents.find_cmp_use_shellcode("4141,4242,4432")
*/
var patterns = patternsArg.split(",")
if (patterns === null || patterns.length==0) {
logln("please add pattern like \"4141\"")
return false;
}
var is_pattern_found = 0;
while (!is_pattern_found) {
host.namespace..Utility.Control.ExecuteCommand("t");
var debugControl = host.namespace..Utility.Control;
// to access debugcontrol from panel : dx .State.Scripts.debug.Contents.host.namespace..Utility.Control
var current_instruction = host.namespace.Debugger.Utility.Control.ExecuteCommand("u eip")[1];
var current_function = host.namespace.Debugger.Utility.Control.ExecuteCommand("u eip")[0];
var extracted_ops = []
if (current_instruction.includes("cmp") || current_instruction.includes("test") ) {
// logln(current_instruction)
var ops = []
if(current_instruction.includes("cmp"))
ops = [current_instruction.split("cmp")[1].split(",")[0],current_instruction.split("cmp")[1].split(",")[1]]
else
ops = [current_instruction.split("test")[1].split(",")[0],current_instruction.split("test")[1].split(",")[1]]
for(var j=0;j<ops.length;j++) {
var operand = ops[j];
if (operand.includes("]") && operand.includes("[")) { // we have memory access
"dword ptr [edi+1A8h]"
var actual_addresss = operand.split("[")[1].split("]")[0] ;
if (actual_addresss.includes("(")) { // ntdll!__security_cookie (77377270)
actual_addresss = actual_addresss.split("(")[1].split(")")[0]
}
var actual_values ;
try {
actual_values = host.namespace.Debugger.Utility.Control.ExecuteCommand("? poi("+actual_addresss+")")[0].split(":")[1].split(" = ")
} catch(err) {
actual_values = host.namespace.Debugger.Utility.Control.ExecuteCommand("dd " + actual_addresss+ " L1")[0]
}
for(var i=0;i<patterns.length;i++){
var pattern = patterns[i];
if (actual_values[0].includes(pattern) ||actual_values[1].includes(pattern) ) // actul value should be
is_pattern_found = 1
}
var addr = host.namespace.Debugger.Utility.Control.ExecuteCommand("? "+actual_addresss)[0].split(" = ")[1]
var data = actual_addresss+" = " + addr +" ["+actual_addresss+"]=" + actual_values[1]
extracted_ops.push(data)
if (is_pattern_found) {
logln("*********We found a match for pattern...********** ")
logln(data)
//host.namespace.Debugger.Utility.Control.ExecuteCommand(".pause")
}
// dx Debugger.State.Scripts.debug.Contents.evalee("var actual_addresss = \"eax+4\"; host.namespace.Debugger.Utility.Control.ExecuteCommand(\"? poi(\"+actual_addresss+\")\")[0]")
}else if(operand.includes("h") || !isNaN(operand)) { // We have constant value
extracted_ops.push("data: "+operand)
} else if(operand.includes("(")) {
extracted_ops.push("data: "+operand.split("(")[1].split(")")[0])
}
else { // we have a register
// logln(current_instruction + " r "+operand)
// logln("operand value "+operand)
var actual_value = host.namespace.Debugger.Utility.Control.ExecuteCommand("r "+operand)[0].split("=")[1]
for(var i=0;i<patterns.length;i++){
var pattern = patterns[i];
if (actual_value.includes(pattern)) // actul value should be
is_pattern_found = 1
}
var data = "Register: "+operand.trim()+" value: " + actual_value
extracted_ops.push(data)
if (is_pattern_found) {
logln("We found a match for pattern in reigster... ")
logln(data)
//host.namespace.Debugger.Utility.Control.ExecuteCommand(".pause")
}
}
}
var call_trace = "";
var tmp = host.namespace.Debugger.Utility.Control.ExecuteCommand("k");
for(var k =0;k<5;k++)
call_trace += tmp[k] + "\n"
logln("current Trace call: " +current_function+ " Instruction: " +current_instruction + "\n" + "Call Trace: \n" + call_trace)
for (let element of extracted_ops) {
logln(element)
if (element.includes("520")) { return;}
}
}
host.namespace.Debugger.Utility.Control.ExecuteCommand("r $t1 = "+ is_pattern_found)
}
return is_pattern_found;
}
function logln(e) {
host.diagnostics.debugLog('\n'+e + '\n\n\n');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment