我是逆向工程的新手。这是我的问题:我正在运行一个程序,我知道在执行过程中将计算一个值“ X ”。现在我如何设置 IDA 或 ollydbg 在内存中第一次出现值 X 时中断。(我猜它类似于内存/数据断点)请帮忙。
在内存中找到特定值时如何使程序停止执行
好吧,几周前我正在实施一个 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”
这有多种解释,您必须以不同的方式处理。
- 值
X是即时计算的。该值用作参数或修饰符,永远不会存储在内存中。
对于这种解释,您必须找到实际计算您的值的代码。您可以设置断点,检查相关寄存器的值,如果未找到该值,则继续。
- 值“X”被计算并存储在内存中的固定位置。
这是最简单的。只需在您知道值必须出现的地址上设置一个内存断点。此外,您可以检查该值,只有在X实际设置该值时才中断。
- 值 'X' 与对象一起计算和存储(使用面向对象的语言)。
在这种情况下,每次运行代码时,该值可能存储在不同的地址中。但是,您仍然应该能够识别使用对象的代码,因此您知道对象(或内存块)的地址。然后,您可以引用此地址并检查该值,如果未达到则继续。
您如何准确地执行这些技术取决于您使用的调试器。我通常使用windbg,并且使用条件断点您可以完成所有这些。更难的部分是找出你的值到底在哪里,因为在现代计算机中你有 4GB 以上的 RAM,所以如果你只是在没有上下文的情况下寻找一个特定的数字,可以在很多地方找到相同的值。
我曾经写过一个小工具来解决这个问题。我创建了一个内存转储并寻找我的价值所在的所有地方。然后我让程序继续并在值改变时进行另一个转储。我只比较了我之前找到的地址。通常只需要 2-3 次迭代就可以找到地址。但是,此方法仅适用于值始终位于同一地址且不随动态分配的内存移动的情况。
您可以尝试使用DIE。
DIE 使用 IDA 的调试器来获取在运行时传入和传出函数的值。执行后,它会生成一个“值视图”窗口,列出它收集的所有值。如果您的价值在那里,您可以看到它的使用/生成位置。请注意,如果该值未传递给函数或从函数返回,它将不会出现在值视图中。
从那里,您可以在相关位置设置断点(或条件断点)并再次调试程序。
不过,这确实需要最新版本的 IDA Pro。