我正在分析一段汇编代码,以提取密钥。
源代码在下面,但是我正在做的是在pop esp
指令后设置一个断点,然后尝试检查堆栈以确定128位密钥。
我的汇编知识仍然很初级,但是我认为正在发生的是该程序使用DWORD
开头的一系列指令构造密钥,然后将其加载到堆栈中。
问题是输出。我在pop esp
调用之后中断了,检查堆栈,但是都被“弄乱了”。
我认为这是我想要的字符串:0xffffd21c ("#'%px$rr 'q#rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
我的问题是,我对执行的理解是错误的,为什么?如何纠正从esp
的乱码中提取人类可读字符串的过程?
我的GDB / PEDA输出...
root@kali:~/ctp/challenge# gdb ./key
GNU gdb (GDB) 8.2
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./key...done.
gdb-peda$ break *0x565560a4
Breakpoint 1 at 0x565560a4
gdb-peda$ r
Starting program: /root/ctp/challenge/key
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0xf7ffd000 --> 0x28f2c
ECX: 0x0
EDX: 0xf7fe4560 (push ebp)
ESI: 0xffffd2ac --> 0xffffd468 ("SHELL=/bin/bash")
EDI: 0x56556000 (<_start>: xor eax,eax)
EBP: 0x0
ESP: 0xffffd218 --> 0xffffd21c ("#'%px$rr 'q#rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
EIP: 0x565560a4 (<_start+164>: pop esi)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x56556099 <_start+153>: push 0x72722478
0x5655609e <_start+158>: push 0x70252723
0x565560a3 <_start+163>: push esp
=> 0x565560a4 <_start+164>: pop esi
0x565560a5 <_start+165>: mov edi,esi
0x565560a7 <_start+167>: mov edx,edi
0x565560a9 <_start+169>: cld
0x565560aa <_start+170>: mov ecx,0x80
[------------------------------------stack-------------------------------------]
0000| 0xffffd218 --> 0xffffd21c ("#'%px$rr 'q#rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
0004| 0xffffd21c ("#'%px$rr 'q#rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
0008| 0xffffd220 ("x$rr 'q#rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
0012| 0xffffd224 (" 'q#rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
0016| 0xffffd228 ("rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
0020| 0xffffd22c ("r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
0024| 0xffffd230 ("w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
0028| 0xffffd234 ("p\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, 0x565560a4 in _start ()
gdb-peda$ x/10s $esp
0xffffd218: "\034\322\377\377#'%px$rr 'q#rq' r\"u$w%vsp\"p\"y#$v' twy#q$yt'p'x$psu \"ww' y'v' srr$#xtvqt$s \"uyt\"pxptuwsr'stry\"v'\"rrw\"ptpwvy''y 'x\"y wrys\"rqq\"uyvv"
0xffffd29d: ""
0xffffd29e: ""
0xffffd29f: ""
0xffffd2a0: "\001"
0xffffd2a2: ""
0xffffd2a3: ""
0xffffd2a4: "P\324\377\377"
0xffffd2a9: ""
0xffffd2aa: ""
gdb-peda$
代码...
global _start
_start:
xor eax,eax
push eax
push dword 0x76767975
push dword 0x22717172
push dword 0x22737972
push dword 0x77207922
push dword 0x78272079
push dword 0x27277976
push dword 0x77707470
push dword 0x22777272
push dword 0x22277622
push dword 0x79727473
push dword 0x27727377
push dword 0x75747078
push dword 0x70227479
push dword 0x75222073
push dword 0x24747176
push dword 0x74782324
push dword 0x72727320
push dword 0x27762779
push dword 0x20277777
push dword 0x22207573
push dword 0x70247827
push dword 0x70277479
push dword 0x24712379
push dword 0x77742027
push dword 0x76242379
push dword 0x22702270
push dword 0x73762577
push dword 0x24752272
push dword 0x20277172
push dword 0x23712720
push dword 0x72722478
push dword 0x70252723
push esp
pop esi
mov edi,esi
mov edx,edi
cld
mov ecx,0x80
mov ebx,0x41
xor eax,eax
push eax
lodsb
xor eax,ebx
stosb
;loop 0xb7 ; offending line
;dec ecx
jnz 0xb7; added in
push esp
pop esi
int3
db 0x0a
答案 0 :(得分:0)
它们没有乱码,它们(大概是)将这些字节正确解释为ASCII字符。
和它们不是一个或多个EIP值。 (即使EIP中不是 ,“ EIP值”有时也会被利用来代表返回地址,但我不认为这种情况在这里发生)。实际的EIP显示效果很好:EIP: 0x565560a4 (<_start+164>: pop esi)
。
如果堆栈中确实包含返回地址,则可以使用x /10xw $esp
或类似的地址。
它看起来像字符串数据。例如0x70 ^ 0x41 = 0x31 = '1'
。和0x23^0x41 = 0x62 = 'b'
。
但是我认为正在发生的是该程序使用开头的DWORD指令序列构造密钥,然后将其加载到堆栈中。
否,它会通过一系列推送在栈上构造 data 。此时,它已经在堆栈中了。
密钥是0x41
中的mov ebx, 0x41
。
然后看起来它有一个低效的循环,应该xor
一次0x41
每个字节一次,但是您注释掉了dec
并留在了一个绝对的分支中0xb7
的地址,它将在Linux下出现段错误。
很明显应该是
.loop: ; do {
lodsb
xor eax,ebx
stosb
dec ecx
jnz .loop ; }while(--ecx);
在前面的设置EDI和ESI = ESP的指令之后,清除了DF以向上执行字符串指令。
这效率极高(在ECX = 0x80字节时一次使用1个字节,并使用慢速loop
指令将其限制为在最近的Intel CPU上每6个周期进行1次迭代),但看起来却不高针对代码大小进行了优化。 (mov eax, 0x41
是5个字节,而push 0x41
/ pop eax
是3个字节)。优化了代码大小的循环,但代码 outside 的速度却倒退了。
效率更高的是xor dword [esi], 0x41414141
/ add esi,4
。 (或者,如果您关心代码大小而不是速度,则可以使用lodsd
作为1字节的方式将ESI增加4。)