x86 程序集 EIP 值未以可读格式显示



我有一段汇编代码,我正在分析它以提取密钥。 源代码如下,但我正在做的是在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: "34322377377#'%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: "01"
0xffffd2a2: ""
0xffffd2a3: ""
0xffffd2a4: "P324377377"
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

它们没有乱码,这些(大概)是将这些字节正确解释为 ASCII 字符。

而且它们不是一个或多个 EIP 值。 ("EIP 值"有时被利用为返回地址说话,即使它们不在EIP 中,但我认为这里不会发生这种情况)。 实际的EIP显示很好:EIP: 0x565560a4 (<_start+164>: pop esi)

如果堆栈确实包含返回地址,则可以使用x /10xw $esp或类似地址。

它看起来像字符串数据。 例如0x70 ^ 0x41 = 0x31 = '1'.和0x23^0x41 = 0x62 = 'b'.

但我认为正在发生的事情是程序使用一系列 DWORD 指令的开头构造密钥,然后将其加载到堆栈中。

不,它通过一系列推送在堆栈上构造数据。 那时它已经在堆栈上了。

关键是0x41,在mov ebx, 0x41


然后看起来它有一个低效的循环,应该0x41一次xor一个字节,但你注释掉了dec并在分支中保留为绝对地址0xb7,这将在 Linux 下出现段错误。

很明显,它应该是

.loop:            ; do {
lodsb
xor  eax,ebx
stosb
dec  ecx
jnz  .loop     ; }while(--ecx);

在前面设置EDI和ESI = ESP的指令之后,并清除DF以字符串指令向上。

这是非常低效的(ECX = 0x80 字节一次使用 1 个字节,并使用慢速loop指令,在最近的英特尔 CPU 上将其限制为每 6 个周期 1 次迭代),但看起来也没有针对代码大小进行优化。 (mov eax, 0x41是 5 个字节,而push 0x41/pop eax为 3 个字节)。 针对代码大小优化循环,但为了速度而优化外部代码是向后的。

效率更高的是xor dword [esi], 0x41414141/add esi,4. (或者,如果您关心代码大小而不是速度,则可以使用lodsd作为将 ESI 增加 4 的 1 字节方式。

最新更新