今天有空接着分析了这个CrackMe(http://bbs.pediy.com/showthread.php?t=147172),但是还是问题重重,菜鸟不容易。搜查了资料没有找到答案,想也想不出。所以再来论坛求助于各位大侠啦。
问题1:子函数sub_401c13不能理解。
enter 0, 0 ; Make Stack Frame for Procedure Parameters
.text:00401C17 ; junk code
.text:00401C1B mov esi, [ebp+arg_4]
.text:00401C1E ; junk code
.text:00401C2C ; junk code
.text:00401C3D mov edi, [ebp+arg_0]
.text:00401C40 ; junk code
.text:00401C4F lodsb ; Load String
.text:00401C50 ; junk code
.text:00401C55 rol al, 6 ; Rotate Left
.text:00401C58 ; junk code
.text:00401C5F ror al, 6 ; Rotate Right
.text:00401C62 ; junk code
.text:00401CB3 ; junk code
.text:00401CD6 add ah, 6 ; Add
.text:00401CD9 cmp al, 6Ch ; Compare Two Operands
.text:00401CDB cmp al, 73h ; Compare Two Operands
.text:00401CDD ; junk code
.text:00401D09 ; ---------------------------------------------------------------------------
.text:00401D09 ; START OF FUNCTION CHUNK FOR sub_401C13
.text:00401D09
.text:00401D09 loc_401D09: ; CODE XREF: sub_401C13+CAj
.text:00401D09 ; DATA XREF: sub_401C13+CAo
.text:00401D09 cmp al, 72h ; Compare Two Operands
.text:00401D0B jmp short loc_401D62 ; Jump
.text:00401D0D ; junk code
.text:00401D4F jnz short loc_401D62 ; Jump if Not Zero (ZF=0)
.text:00401D51 fmul st, st(1) ; Multiply Real
.text:00401D53 test eax, 7BF7F8D8h ; Logical Compare
.text:00401D62 loc_401D62: ; CODE XREF: sub_401C13+F8j
.text:00401D62 ; sub_401C13+13Cj
.text:00401D62 cmp al, 0 ; Compare Two Operands
.text:00401D64 jnz loc_401C40 ; Jump if Not Zero (ZF=0)
.text:00401D6A ; junk code
.text:00401D88 mov String+3Ch, 5
.text:00401D8F leave ; High Level Procedure Exit
.text:00401D90 retn 8 ; Return Near from Procedure
这个子函数,我的理解是用来判断'S‘的个数的。但是,就是不知道哪里体现出来了。
1、esi寄存器保存的数据是用来干什么的?
2、edi存放的每个字符,先rol 6再rol 6,貌似对字符没有影响吧。然后’S‘的ASCII码是0x53,可是接下来只是运行add ah,6。然后不断的cmp al和各个奇怪的数值,是在不明白,到最后cmp al,0语句怎么会true。al貌似在这之前一直没有变过,到底是怎么实现判断是否为’S‘的?然后如何判定’S‘的个数多余5,貌似没有记录。
问题2:关于ReadFile和WriteFile的函数的理解问题。
BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);
这里,我理解为lpNumberOfBytesRead参数是个指针,指向的数字意义是已经读取的Byte的个数。在这个CrackMe中,
cmp NumberOfBytesWritten, 2 ; Compare Two Operands
jz loc_401B1D ; Jump if Zero (ZF=1)
这个比较是否用来判断已写入的个数是否等于2个。这里小小地困惑下NumberOfBytesWritten此时又变为数据了。所以小郁闷下,特来求证。
问题3:IDA使用问题。
次CrackMe中大量出现:
push (offset aConnectedToXx_+66h) ; lpBuffer
类似语句,而:
.data:00404000 aConnectedToXx_ db 'Connected to XX.XX.XX.XX, hosted by HF',0Ah
.data:00404000 ; DATA XREF: start+1F7o
.data:00404000 db 0Dh,'Shadow',27h,'s crackme server version 1.0 running under winblows',0Ah
.data:00404000 db 0Dh,0Ah
.data:00404000 db 0Dh,'login:',0Ah
.data:00404000 db 0Dh,'password:',0Ah
.data:00404000 db 0Dh,'login failed',0Ah
.data:00404000 db 0Dh,'Access denied',0Ah
.data:00404000 db 0Dh,'Only guest access granted, try harder',0Ah
.data:00404000 db 0Dh,0Ah
.data:00404000 db 0Dh,'Root access. send solution to lazarus666@gnwmail.com',0Ah
.data:00404000 db 0Dh,0
.data:004040F6 db 0
.data:004040F7 db 0
.data:004040F8 db 0
我想请教下各位大侠,是否有方法把aConnectedToXx_+66h的确切位置显示出来,或者说是,我不想自己去一个字符一个字符的计算加上0x66是到哪个字符串,IDA有没有提供类似的功能帮助。
就剩下这3个问题了,这个CrackMe就可以更进一步理解了,希望各位大侠不吝赐教,谢谢各位。
[课程]FART 脱壳王!加量不加价!FART作者讲授!