x86 程序集 EIP 值未以可读格式显示
x86 Assembly EIP Value not displaying in readable format
我正在分析一段汇编代码以提取密钥。
源代码在下面,但我正在做的是在 pop esp
指令之后设置一个断点,然后尝试检查堆栈以确定 128 位密钥。
我的汇编知识仍然很初级,但我认为正在发生的事情是程序用 DWORD
指令的开头系列构造密钥,然后将其加载到堆栈上。
问题出在输出上。我在 pop esp
调用后中断,检查堆栈,但都是 'scrambled'.
我认为这是我想要的字符串: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: "4277#'%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: "[=10=]1"
0xffffd2a2: ""
0xffffd2a3: ""
0xffffd2a4: "P477"
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 value" 有时会利用 return 地址,即使它们在 EIP 中是 而不是 ,但我认为这不会发生在这里)。实际EIP显示没问题:EIP: 0x565560a4 (<_start+164>: pop esi)
.
如果堆栈确实包含 return 个地址,您将使用 x /10xw $esp
或类似的地址。
看起来像字符串数据。例如0x70 ^ 0x41 = 0x31 = '1'
。和 0x23^0x41 = 0x62 = 'b'
.
But what I think is happening is the program constructs the key with the opening series of DWORD instructions and then loads it onto the stack.
不,它通过一系列的压栈在堆栈上构造了数据。那时它已经在堆栈上。
关键是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以串指令向上。
这是非常低效的(一次 1 个字节,ECX = 0x80 字节,并使用慢速 loop
指令,在最近的 Intel CPU 上将其限制为每 6 个周期 1 次迭代),但也没有看起来没有针对 code-size 进行优化。 (mov eax, 0x41
是 5 个字节,而 push 0x41
/ pop eax
是 3 个字节)。优化 code-size 的循环,但 outside 的速度代码是倒退的。
效率更高的是 xor dword [esi], 0x41414141
/ add esi,4
。 (或者,如果您关心 code-size 而不是速度,则可以使用 lodsd
作为 1 字节的方式将 ESI 递增 4。)
我正在分析一段汇编代码以提取密钥。
源代码在下面,但我正在做的是在 pop esp
指令之后设置一个断点,然后尝试检查堆栈以确定 128 位密钥。
我的汇编知识仍然很初级,但我认为正在发生的事情是程序用 DWORD
指令的开头系列构造密钥,然后将其加载到堆栈上。
问题出在输出上。我在 pop esp
调用后中断,检查堆栈,但都是 'scrambled'.
我认为这是我想要的字符串: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: "4277#'%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: "[=10=]1"
0xffffd2a2: ""
0xffffd2a3: ""
0xffffd2a4: "P477"
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 value" 有时会利用 return 地址,即使它们在 EIP 中是 而不是 ,但我认为这不会发生在这里)。实际EIP显示没问题:EIP: 0x565560a4 (<_start+164>: pop esi)
.
如果堆栈确实包含 return 个地址,您将使用 x /10xw $esp
或类似的地址。
看起来像字符串数据。例如0x70 ^ 0x41 = 0x31 = '1'
。和 0x23^0x41 = 0x62 = 'b'
.
But what I think is happening is the program constructs the key with the opening series of DWORD instructions and then loads it onto the stack.
不,它通过一系列的压栈在堆栈上构造了数据。那时它已经在堆栈上。
关键是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以串指令向上。
这是非常低效的(一次 1 个字节,ECX = 0x80 字节,并使用慢速 loop
指令,在最近的 Intel CPU 上将其限制为每 6 个周期 1 次迭代),但也没有看起来没有针对 code-size 进行优化。 (mov eax, 0x41
是 5 个字节,而 push 0x41
/ pop eax
是 3 个字节)。优化 code-size 的循环,但 outside 的速度代码是倒退的。
效率更高的是 xor dword [esi], 0x41414141
/ add esi,4
。 (或者,如果您关心 code-size 而不是速度,则可以使用 lodsd
作为 1 字节的方式将 ESI 递增 4。)