在内存中找到特定值时如何使程序停止执行

逆向工程 艾达 ollydbg 补丁反转
2021-07-11 13:27:42

我是逆向工程的新手。这是我的问题:我正在运行一个程序,我知道在执行过程中将计算一个值“ X ”。现在我如何设置 IDA 或 ollydbg 在内存中第一次出现值 X 时中断。(我猜它类似于内存/数据断点)请帮忙。

4个回答

好吧,几周前我正在实施一个 ollyscript,它会在找到所需字母/数字值的每一行上触发条件断点。

该程序使用户可以选择以下 3 种方法之一:

1- 跟踪方法(适用于数字)

2- 内存断点

3- 通过设置无条件断点进行智能研究(通过两次工作)

  • 黄金剧本:
COE 
LC  
log " This script is realised by AGAWA001 of StackExchange "    
log " This script should be executed on ODbgScript version +1.82.6" 
log " This script must rerun twice atleast in case of smartresearch"    
log " you must restart your program once terminated to clear useless breakpoints"   
log " This script is used to check existence of an alpha/numeric value in memory"   
log " Unicode strings arent suppoted try to input first two unicode characters as number"   
log " in case when script stops, press spacebar focused on script window to force it to run"    
log " This script removes all beakpoints prealably set up and changes labels from command lines"    
log " To run this script as quick as possible, ollydbg window is prefered to be minimized during execution "    
log " All insider windows (log window,bp window,memory ,...) must be closed apart script window to ensure shortest runtime" 
log " Trace procedure can encounter T-flag error, in this case try to get a grasp on it by binding esc key focused on script window"    
log " Some debuggers dont support ask command, so values must be injected manually and carefully instead of userprompt command in same line"    

log "--------------------------------------------------------------------------------------"    
log " This is beta version, Contact me whether you find any bugs, regards." 
log "--------------------------------------------------------------------------------------"    

var str 
var tmp 
var start   
var finish  
var addr    
var ending  
var beginning   
var val 
var value   
var swtch   
var stack   
var stackend    
var buff    
var offset  
var dll 
var processkill 
mov processkill,0   
mov offset,4    
alloc 1000                          
mov buff, $RESULT   
mov offst,ff    
GMEMI esp, MEMORYBASE   
mov stack,$RESULT   
GMEMI $RESULT, MEMORYSIZE   
mov stackend,$RESULT    
add stackend,stack  
gmi eip,MODULEBASE  
mov start,$RESULT   
mov finish,$RESULT  
gmi eip,MODULESIZE  
add finish,$RESULT  
gcmt finish 
cmp $RESULT,"complete"  
je bypass   
cmp $RESULT,"done"  
je exit 
preop eip   
gcmt $RESULT    
cmp $RESULT,"ready" 
je check2   
preop eip   
gcmt $RESULT    
mov val,$RESULT 
len $RESULT 
ifg $RESULT,1   
atoi val    
mov val,$RESULT 
mov dll,0   
ife val>>1f,1   
mul val,-1  
mov addr,eip-val    
jmp boucl   
else    
mov addr,eip+val    
jmp boucl2  
endif   
endif   
check2: 
mov processkill,1   
bypass: 
mul offst,10    
ask "Enter value to look for (preceded by 'str:' in case of a formatted string ex: str:password ) " 
add offst,buff  
cmp $RESULT, 0  
je  theend  
mov str,$RESULT 
mov value,$RESULT   
str str 
len str 
mov tmp,$RESULT 
cmp tmp,5   
jb ok   
str str 
scmp  str, "str:", 4    
jne ok  
buf str 
mov [esp-100],str   
mov value,0 
mov value,[esp-100+4]   
keepon: 
mov [buff+offset-4],[esp-100+offset]    
add offset,4    
cmp tmp,offset  
jbe nok 
jmp keepon  
ok: 
mov [buff+offset-4],value   
nok:    
cmp processkill,1   
je loop 
MSGYN "do you want to set breakpoints on dlls ? "   
ifeq $RESULT, 0 
mov dll,0   
else    
mov dll,1   
endif   
cmp $RESULT,2   
je theend   
jmp firstcheck  
returnback: 
mov val,value   
MSGYN "do you want to trace the information ? press no to proceed smart research "  
cmp $RESULT, 2  
jne traced  




firstcheck: 
mov val,0   
mov addr,0  
mov tmp,0   
mov str,0   
repeat: 
mov [2*str+offst],c0+str    
add str,1   
cmp str,3   
jl repeat   
mov str,value   
buf str 
findmem str, addr   
cmp $RESULT, 0  
je cont 
mov addr,$RESULT    
itoa addr   
log "value found in memory at " + $RESULT   
ifeq tmp,0  
msgyn "value found in memory would you like to set memory breakpoint there (see log) ?" 
mov tmp,$RESULT 
cmp $RESULT,2   
je returnback   
endif   
mov val,addr    
GMEMI addr, MEMORYBASE  
mov addr,$RESULT    
gmi addr,PATH   
add buff,300    
mov [buff],$RESULT  
len [buff]  
mov str,$RESULT 
add str,buff    
sub str,3   
cmp [str],"dll" 
sub buff,300    
je cont 
GMEMI addr, MEMORYSIZE  
cmp val,start   
jb performm 
cmp val, finish 
ja performm 
add addr,$RESULT    
jmp repeat  
performm:   
cmp val,stack   
jb performm2    
cmp val, stackend   
ja performm2    
mov addr,val    
mov str,4   
jmp changeplan  
performm2:  
mov str,$RESULT     
sub str,1   
changeplan: 
cmp tmp,0   
je saut 
bprm addr,str   
mov val,[buff+400]  
mov [buff+404+val],addr 
mov [buff+408+val],str  
add val,8   
mov [buff+400],val  
saut:   
add addr,str    
cmp tmp,0   
je repeat   
jmp cont    





traced: 
cmp $RESULT, 0  
je smartsearch  



itoa val    
mov val,$RESULT 
concatenate:    
len val 
cmp $RESULT,8   
je stopit   
mov val,"0"+val 
jmp concatenate 
stopit: 
mov str, " EAX==" + val+ " | EBX==" + val+ " | ECX==" + val+ " | EDX==" + val+ " | ESI==" + val+ " | EDI==" + val   
log "---------------------value to trace is---------------------------" 
log str 
log "-----------------------------------------------------------------" 
ticnd str   
mov swtch,1 
jmp passover    
trace:  
precontinue:    
sti 
mov addr,eip    
ti  
cmp eip,addr    
je precontinue  
passover:   
ifeq dll,0  
cmp eip,start   
jb run  
cmp eip,finish  
ja run  
jmp continue    
run:    
rtr 
sti 
cmp eip,start   
jb run  
cmp eip,finish  
ja run  
jmp trace   
endif   
continue:   
preop eip   
mov addr,$RESULT    
GOPI addr, 1, DATA  
cmp $RESULT,value   
je detected1    
GOPI addr, 2, DATA  
cmp $RESULT,value   
je detected2    
GOPI addr, 1, ADDR  
cmp $RESULT,7   
ja checkval 
mov val,[buff]  
cmp swtch,1 
je trace    
jmp redo2   
checkval:   
mov tmp,0   
cmp [$RESULT],value 
and [offst+1],ff00ff00  
mov val,7   
je affect   
add tmp,1   
cmp [$RESULT+1],value   
je affect   
add tmp,1   
cmp [$RESULT+2],value   
je affect   
add tmp,1   
cmp [$RESULT+3],value   
je affect   
GOPI addr, 2, ADDR  
cmp $RESULT,8   
add [offst+1],400050    
add [offst+1],val   
add [offst+3],val   
jb compare  
jmp round2  
affect: 
add [offst+1],400050    
add [offst+1],val   
add [offst+3],val   
itoa $RESULT+tmp    
mov addr,$RESULT    
mov tmp,0   
mov val, buff+100   
jmp concat  
round2: 
mov tmp,0   
cmp [$RESULT],value 
je affect   
add tmp,1   
cmp [$RESULT+1],value   
je affect2  
add tmp,1   
cmp [$RESULT+2],value   
je affect2  
add tmp,1   
cmp [$RESULT+3],value   
je affect2  
cmp swtch,1 
je trace    
jmp redo2   
affect2:    
itoa $RESULT+tmp    
mov addr,$RESULT    
mov tmp,0   
mov val, buff+100   
jmp concat  
compare:    
mov val,[buff]  
mov [buff+e08],31303041 
cmp swtch,1 
je trace    
jmp redo2   
detected1:  
GOPI addr, 1, ADDR  
jmp branch  
detected2:  
GOPI addr, 2, ADDR  
branch:     
mov tmp,$RESULT 
mov str,addr    
itoa str    
mov str,$RESULT 
itoa value  
cmp tmp,0   
je eaxx 
cmp tmp,1   
je ecxx 
cmp tmp,2   
je edxx 
cmp tmp,3   
je ebxx 
cmp tmp,6   
je esii 
cmp tmp,7   
je edii 
log "eip="+str  
mov addr,tmp    
mov tmp,0   
mov val, buff+100   
itoa addr   
mov addr,$RESULT    
mov str,0   
concat: 
mov str,0   
mov str,[buff+tmp]  
itoa str    
mov str,$RESULT 
mov [val] , "[" 
mov [val+1],  addr  
len [val]   
mov [val+$RESULT], "] == "  
mov [val+$RESULT+5], str    
add val,$RESULT+5   
len [val]   
mov [val+$RESULT], "&"  
add val,$RESULT+1   
mov [val],0 
add tmp,1   
atoi addr   
mov addr,0  
mov addr,$RESULT    
add addr,1  
cmp offset-4,tmp    
jbe dobp    
cmp [addr],[buff+tmp]   
jne dobp2   
itoa addr   
mov addr,$RESULT    
jmp concat  
dobp:   
itoa addr   
log "found at :" + $RESULT  
msgyn "perfect value found in memory ,would you like to clear all previous conditional breakpoints? press no to keep all breakpoints, cancel to stop script (see log window)"   
ifeq $RESULT,1  
bc  
else    
ifeq $RESULT,2  
jmp theend  
endif   
endif   
dobp2:  
mov [val-1],0   
mov [buff+e04],57414741 
gstr buff+100   
BPCND eip, $RESULT  
cmt finish,"done"   
itoa eip    
LBL eip,"no"+$RESULT    
fill buff+100, val-buff-100, 0  
mov val,[buff]  
cmp swtch,1 
je trace    
jmp redo2   
eaxx:   
log "eip="+str  
BPCND eip, "EAX == " + $RESULT  
gcmt start  
cmp $RESULT,"done"  
jne check4  
gcmt finish 
cmp $RESULT,"complete"  
je check4   
itoa eip    
LBL eip,"no"+$RESULT    
check4: 
cmp swtch,1 
je trace    
jmp redo2   
ebxx:   
log "eip="+str  
BPCND eip, "EBX == " + $RESULT  
gcmt start  
cmp $RESULT,"done"  
jne check3  
gcmt finish 
cmp $RESULT,"complete"  
je check3   
itoa eip    
LBL eip,"no"+$RESULT    
check3: 
gcmt start  
cmp $RESULT,"done"  
jne check5  
gcmt finish 
cmp $RESULT,"complete"  
je check5   
itoa eip    
LBL eip,"no"+$RESULT    
check5: 
cmp swtch,1 
je trace    
jmp redo2   
ecxx:   
log "eip="+str  
BPCND eip, "ECX == " + $RESULT  
gcmt start  
cmp $RESULT,"done"  
jne check6  
gcmt finish 
cmp $RESULT,"complete"  
je check6   
itoa eip    
LBL eip,"no"+$RESULT    
check6: 
cmp swtch,1 
je trace    
jmp redo2   
edxx:   
log "eip="+str  
BPCND eip, "EDX == " + $RESULT  
gcmt start  
cmp $RESULT,"done"  
jne check7  
gcmt finish 
cmp $RESULT,"complete"  
je check7   
itoa eip    
LBL eip,"no"+$RESULT    
check7: 
cmp swtch,1 
je trace    
jmp redo2   
esii:   
log "eip="+str  
BPCND eip, "ESI == " + $RESULT  
gcmt start  
cmp $RESULT,"done"  
jne check8  
gcmt finish 
cmp $RESULT,"complete"  
je check8   
itoa eip    
LBL eip,"no"+$RESULT    
check8: 
cmp swtch,1 
je trace    
jmp redo2   
edii:   
log "eip="+str  
BPCND eip, "EDI == " + $RESULT  
gcmt start  
cmp $RESULT,"done"  
jne check9  
gcmt finish 
cmp $RESULT,"complete"  
je check9   
itoa eip    
LBL eip,"no"+$RESULT    
check9: 
cmp swtch,1 
je trace    
jmp redo2   



cont:   

log "-----------------end memorybreakpoints---------------------"   
loop:   
COE 
erun    


ifeq dll,0  
cmp eip,start   
jb run2 
cmp eip,finish  
ja run2 
jmp continue2   
run2:   
BPMC    
redoit: 
COE 
erun    
cmp eip,start   
jb redoit   
cmp eip,finish  
ja redoit   
mov val,0   
mov str,buff+404    
bpaffect:   
bprm [str],[str+4]  
add str,8   
add val,8   
cmp [buff+400],val  
jne bpaffect    
jmp loop    
continue2:  
endif                           



mov addr, eip   
GOPI addr, 1, DATA  
cmp $RESULT, value  
je detected1    
GOPI addr, 2, DATA  
cmp $RESULT, value  
je detected2    
GOPI addr, 1, ADDR  
cmp $RESULT,7   
ja checkval 
GOPI addr, 2, ADDR  
cmp $RESULT,8   
jb redo2    
jmp round2  
detected1:  
GOPI addr, 1, ADDR  
jmp branch  
detected2:  
GOPI addr, 2, ADDR  
jmp branch  



ifeq dll,0  
cmp eip,start   
jb run2 
cmp eip,finish  
ja run2 
jmp continue2   
run2:   
BPMC    
redoit: 
COE 
rtr 
sti 
cmp eip,start   
jb redoit   
cmp eip,finish  
ja redoit   
mov val,0   
mov str,buff+404    
bpaffect:   
bprm [str],[str+4]  
add str,8   
add val,8   
cmp [buff+400],val  
jne bpaffect    
jmp loop    
continue2:  
endif                           


redo2:  

jmp loop    



smartsearch:    
mov dll,0   
mov addr, eip   
boucl:  
mov str,addr    
preop addr  
ifeq $RESULT,addr-1 
preop $RESULT   
mov addr,$RESULT    
jmp boucl   
endif   
mov addr,$RESULT    
cmp addr,str    
je finishit 
opcode addr 
mov [buff+200],$RESULT_1    
mov str,buff+200    
ckecknext:  
add str,1   
scmp  [str], "[", 1 
je dobreak  
cmp [str],0 
je boucll   
jmp ckecknext   
dobreak:    
bp  addr    
mov dll,addr-eip    
itoa dll    
mov dll,$RESULT 
preop eip   
cmt $RESULT,dll 
mov val,addr    
itoa val    
LBL val,"yes"+$RESULT   
boucll: 
gstr buff+200   
len $RESULT 
fill buff+200, $RESULT, 0   
jmp boucl   

finishit:   
mov dll,0   
mov start,addr  
mov addr, eip   
boucl2: 
GCI addr, size  
cmp $RESULT,0   
je loopp    
mov addr,addr +$RESULT  
preop addr  
ifeq $RESULT,addr-1 
jmp boucl2  
endif   
opcode addr 
cmp addr,finish 
jae loopp   
mov [buff+200],$RESULT_1    
mov str,buff+200    
ckecknext2: 
add str,1   
scmp  [str], "[", 1 
je dobreak2 
cmp [str],0 
je boucll2  
jmp ckecknext2  
dobreak2:   
mov dll,addr-eip    
itoa dll    
mov dll,$RESULT 
preop eip   
cmt $RESULT,dll 
GCI addr, size  
bp  addr    
mov val,addr    
itoa val    
LBL val,"yes"+$RESULT   
boucll2:    
gstr buff+200   
len $RESULT 
fill buff+200, $RESULT, 0   
jmp boucl2  

loopp:  
preop eip   
cmt $RESULT,"ready" 
jmp loop    

exit:   
mov val,start   
again:  
ifeq val,finish 
jmp lafin   
endif   
endif   
mov str,""  
glbl val    
ifNeq $RESULT,0 
MOV str,$RESULT 
endif   
scmp str,"yes",3    
jne skipit  
bc val  
lbl val,""  
skipit: 
GCI val, size   
mov val,val+$RESULT 
jmp again   
lafin:  
preop eip   
cmt $RESULT,""  
cmt finish,"complete"   
msg "finished, save a copy of ./udd/<exename>.udd to store script results"  
theend: 
Ret                     
  • 能否将您发现的任何错误报告给此电子邮件 atagawa@gmail.com - 最好的问候 -

我不会说我是 RE 的新手,但我肯定不是专家,所以请对我的回答持保留态度。很有可能,您实际寻找的可能不是实际值,而是该值与您的程序的关系,即;没有任何上下文或维度,数字 42 并不真正意味着任何东西。

您所描述的将是一种非常天真的方法来查找程序如何处理和存储数据,并且有效地实现它的唯一方法是不断搜索整个内存区域(大小很容易达到几兆字节),每次给定时刻 -如果它实际上以任何方式将值存储在内存中- 或者,在每条指令处停下来查看是否对您的值进行了任何引用。

这并非不可能,但可能不切实际。正如评论中提到的,RE 执行此操作的方法是找到您的价值可能实际出现的上下文,例如,如果您正在视频游戏中寻找您的健康状况,您将首先找到任何可以治愈的代码你或伤害你或检查你是否还活着等。

没有更多信息,我们无法为您提供更多帮助,也许您可​​以编辑您的问题以提供更多信息?

我知道在执行过程中将计算一个值“X”

这有多种解释,您必须以不同的方式处理。

  1. X是即时计算的。该值用作参数或修饰符,永远不会存储在内存中。

对于这种解释,您必须找到实际计算您的值的代码。您可以设置断点,检查相关寄存器的值,如果未找到该值,则继续。

  1. 值“X”被计算并存储在内存中的固定位置。

这是最简单的。只需在您知道值必须出现的地址上设置一个内存断点。此外,您可以检查该值,只有在X实际设置该值时才中断

  1. 值 'X' 与对象一起计算和存储(使用面向对象的语言)。

在这种情况下,每次运行代码时,该值可能存储在不同的地址中。但是,您仍然应该能够识别使用对象的代码,因此您知道对象(或内存块)的地址。然后,您可以引用此地址并检查该值,如果未达到则继续。

您如何准确地执行这些技术取决于您使用的调试器。我通常使用windbg,并且使用条件断点您可以完成所有这些。更难的部分是找出你的值到底在哪里,因为在现代计算机中你有 4GB 以上的 RAM,所以如果你只是在没有上下文的情况下寻找一个特定的数字,可以在很多地方找到相同的值。

我曾经写过一个小工具来解决这个问题。我创建了一个内存转储并寻找我的价值所在的所有地方。然后我让程序继续并在值改变时进行另一个转储。我只比较了我之前找到的地址。通常只需要 2-3 次迭代就可以找到地址。但是,此方法仅适用于值始终位于同一地址且不随动态分配的内存移动的情况。

您可以尝试使用DIE

DIE 使用 IDA 的调试器来获取在运行时传入和传出函数的值。执行后,它会生成一个“值视图”窗口,列出它收集的所有值。如果您的价值在那里,您可以看到它的使用/生成位置。请注意,如果该值未传递给函数或从函数返回,它将不会出现在值视图中。

从那里,您可以在相关位置设置断点(或条件断点)并再次调试程序。

不过,这确实需要最新版本的 IDA Pro。