xor 不同长度的十六进制字符串 NASM
xor hex strings of different length NASM
我正在试验基本的 XOR 函数,我正在尝试对用户输入的十六进制字符串进行异或运算,即 0x43424143
针对 0x41
.
的键
我编写了有效的代码,但我对返回的一些奇怪结果有点好奇。下面编写的代码用于 NASM,它将在 Windows 上编译和 运行(我正在使用外部 C 库函数 scanf
和 printf
)。
我有几个版本,一个以十六进制字符串作为输入,另一个是硬编码的,第二个版本只是为了让事情简单化,同时弄清楚其他一些事情。
两个版本都给出了相同的奇怪输出,我很确定这是错误的。我只是很好奇我是否遗漏了任何明显的事情,我仍然是一个装配和逆向工程方面的大菜鸟。这有点晦涩,所以如果没有明显的地方我出错了,那么我会很高兴地继续研究它,直到找到问题所在。
section .data ;Constant Variable declared here
msg db "Prompt: ", 0
msg2: db 'RESULT: %x : %x ,10,0
fmt db "%s", 0
section .bss ;Reserve data for modifiable variables declared here, i.e. resb in NASM = reserve bytes
inpt resb 155
section .text ;Executable code here
extern _printf ;Calling external C lib function printf, scanf
extern _scanf
global _main ;Main function
_main:
push ebp
mov ebp, esp ;Set up the stack frame to set up the main function
push msg ;The initial prompt
call _printf
add esp, 4
push inpt ;Get user input
push fmt
call _scanf
add esp, 8
xor eax, eax ;Clean things up, ensure that there is no garbage in eax before we start to XOR things
push eax
;push DWORD(0x70757573) ;An old local variable when I was hard coding what I was xoring.
push inpt
push esp
pop esi
mov edi,esi
mov edx,edi
cld ;Clearing th3e direction flag
mov ecx,0x80
mov ebx,0x41 ;hardcoded our key to XOR the input with
mov eax, inpt
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
stosb ;Store the result in EDI.
push edi ;Push EDI to be printed, Result shoudl be stored here via the stosb instruction
push msg2 ;Push the result print message
call _printf ;call the print function
add esp, 20 ;This cleans up the stack. We pushed 5 things onto the stack each were 4 bytes long.
mov esp, ebp ;Destroy the stack frame after the function has finished
pop ebp
ret
代码的简化和缩短版本,没有提示:
section .data ;Constant Variable declared here
msg: db 'RESULT: %x ',10,0
var1: dw 0x70757573 ;hex string to be XOR'd
var2: db 0x41 ;Xor key to use
section .text ;Executable code here
extern _printf ;Calling external C lib function printf
global _main ;Main function
_main:
push ebp ;Set up the stack frame to set up the main function
mov ebp, esp ;
sub esp, 4 ;Reserve space for a 32 bit variable. [4 bytes = 8*4=32]
mov eax, [var1] ;Variable 1 to be XOR'd
mov ebx, [var2] ;Variable 2, The key to xor var1 with
xor eax, ebx ;The XOR function
push eax ;Push eax which should contain the result
push msg ;push the result message
call _printf ;call the print function
add esp, 8 ;clean up the stack
mov esp, ebp ;Destroy the stack frame after the function has finished
pop ebp
ret
说明
stosb ;Store the result in EDI.
将AL的内容存入EDI包含的内存地址
但是你显示的是EDI的值。所以你显示的是地址;大概您想查看看起来像是 32 位的 XOR 操作的内容。所以而不是
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
stosb ;Store the result in EDI.
push edi ;Push EDI to be printed, Result shoudl be stored here via the stosb instruction
push msg2 ;Push the result print message
call _printf ;call the print function
相反,您可能想要
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
push eax ;Push result to be printed
push msg2 ;Push the result print message
call _printf ;call the print function
但是,这也有一个问题。 msg2
可能意味着 RESULT: %x : %x \n
(您的程序集中缺少结束引号)。更重要的是,它需要格式化两个整数值。所以应该推送一个额外的值:
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
push eax ;Push result to be printed
push (something else)
push msg2 ;Push the result print message
mov eax, inpt
xor eax,ebx
您实际上并没有使用通过 call _scanf
获得的输入!使用 NASM 您需要使用方括号来获取内存内容。没有它们,您只能在 EAX
寄存器中获得 inpt 的地址。
mov eax, [inpt]
xor eax, ebx
push esp
pop esi
这真的只是 mov esi, esp
。
add esp, 20 ;This cleans up the stack. We pushed 5 things onto the stack each were 4 bytes long.
错了!您的代码在堆栈上只有 16 个字节。您在 pop esi
.
之后立即删除了 第 5 件事 push esp
最后要显示单号结果,相应地更改格式字符串并使用:
msg2: db 'RESULT: %x ',10,0
...
mov eax, [inpt]
xor eax, ebx
push eax ;Push EAX to be printed
push msg2 ;Push the result print message
call _printf ;call the print function
add esp, 4
最后的建议:不要在程序中留下旧代码!您首先尝试使用硬编码数字 (0x70757573),然后切换到输入,但您没有删除一些之前相关的说明。这样做会产生一个包含多个错误的难以阅读的程序。
xor eax, eax ???
push eax ???
;push DWORD(0x70757573) ???
push inpt ???
push esp ???
pop esi ???
mov edi,esi ???
mov edx,edi ???
cld ???
mov ecx,0x80 ???
mov ebx,0x41
mov eax, inpt
xor eax,ebx
stosb ???
var1: dw 0x70757573 ;hex string to be XOR'd
var2: db 0x41 ;Xor key to use
您将这些变量用作 dword 但您已将它们定义为 word 和 byte!
要么将它们重新定义为双字:
var1: dd 0x70757573 ;hex string to be XOR'd
var2: dd 0x41 ;Xor key to use
或更改使用它们的代码:
movzx eax, word [var1] ;Variable 1 to be XOR'd
movzx ebx, byte [var2] ;Variable 2, The key to xor var1 with
或两者都做:
var1: dd 0x70757573 ;hex string to be XOR'd
var2: db 0x41 ;Xor key to use
...
mov eax, [var1] ;Variable 1 to be XOR'd
movzx ebx, byte [var2] ;Variable 2, The key to xor var1 with
我正在试验基本的 XOR 函数,我正在尝试对用户输入的十六进制字符串进行异或运算,即 0x43424143
针对 0x41
.
我编写了有效的代码,但我对返回的一些奇怪结果有点好奇。下面编写的代码用于 NASM,它将在 Windows 上编译和 运行(我正在使用外部 C 库函数 scanf
和 printf
)。
我有几个版本,一个以十六进制字符串作为输入,另一个是硬编码的,第二个版本只是为了让事情简单化,同时弄清楚其他一些事情。
两个版本都给出了相同的奇怪输出,我很确定这是错误的。我只是很好奇我是否遗漏了任何明显的事情,我仍然是一个装配和逆向工程方面的大菜鸟。这有点晦涩,所以如果没有明显的地方我出错了,那么我会很高兴地继续研究它,直到找到问题所在。
section .data ;Constant Variable declared here
msg db "Prompt: ", 0
msg2: db 'RESULT: %x : %x ,10,0
fmt db "%s", 0
section .bss ;Reserve data for modifiable variables declared here, i.e. resb in NASM = reserve bytes
inpt resb 155
section .text ;Executable code here
extern _printf ;Calling external C lib function printf, scanf
extern _scanf
global _main ;Main function
_main:
push ebp
mov ebp, esp ;Set up the stack frame to set up the main function
push msg ;The initial prompt
call _printf
add esp, 4
push inpt ;Get user input
push fmt
call _scanf
add esp, 8
xor eax, eax ;Clean things up, ensure that there is no garbage in eax before we start to XOR things
push eax
;push DWORD(0x70757573) ;An old local variable when I was hard coding what I was xoring.
push inpt
push esp
pop esi
mov edi,esi
mov edx,edi
cld ;Clearing th3e direction flag
mov ecx,0x80
mov ebx,0x41 ;hardcoded our key to XOR the input with
mov eax, inpt
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
stosb ;Store the result in EDI.
push edi ;Push EDI to be printed, Result shoudl be stored here via the stosb instruction
push msg2 ;Push the result print message
call _printf ;call the print function
add esp, 20 ;This cleans up the stack. We pushed 5 things onto the stack each were 4 bytes long.
mov esp, ebp ;Destroy the stack frame after the function has finished
pop ebp
ret
代码的简化和缩短版本,没有提示:
section .data ;Constant Variable declared here
msg: db 'RESULT: %x ',10,0
var1: dw 0x70757573 ;hex string to be XOR'd
var2: db 0x41 ;Xor key to use
section .text ;Executable code here
extern _printf ;Calling external C lib function printf
global _main ;Main function
_main:
push ebp ;Set up the stack frame to set up the main function
mov ebp, esp ;
sub esp, 4 ;Reserve space for a 32 bit variable. [4 bytes = 8*4=32]
mov eax, [var1] ;Variable 1 to be XOR'd
mov ebx, [var2] ;Variable 2, The key to xor var1 with
xor eax, ebx ;The XOR function
push eax ;Push eax which should contain the result
push msg ;push the result message
call _printf ;call the print function
add esp, 8 ;clean up the stack
mov esp, ebp ;Destroy the stack frame after the function has finished
pop ebp
ret
说明
stosb ;Store the result in EDI.
将AL的内容存入EDI包含的内存地址
但是你显示的是EDI的值。所以你显示的是地址;大概您想查看看起来像是 32 位的 XOR 操作的内容。所以而不是
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
stosb ;Store the result in EDI.
push edi ;Push EDI to be printed, Result shoudl be stored here via the stosb instruction
push msg2 ;Push the result print message
call _printf ;call the print function
相反,您可能想要
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
push eax ;Push result to be printed
push msg2 ;Push the result print message
call _printf ;call the print function
但是,这也有一个问题。 msg2
可能意味着 RESULT: %x : %x \n
(您的程序集中缺少结束引号)。更重要的是,它需要格式化两个整数值。所以应该推送一个额外的值:
xor eax,ebx ;XOR the value in EAX with the x41 Value in EBX
push eax ;Push result to be printed
push (something else)
push msg2 ;Push the result print message
mov eax, inpt xor eax,ebx
您实际上并没有使用通过 call _scanf
获得的输入!使用 NASM 您需要使用方括号来获取内存内容。没有它们,您只能在 EAX
寄存器中获得 inpt 的地址。
mov eax, [inpt]
xor eax, ebx
push esp pop esi
这真的只是 mov esi, esp
。
add esp, 20 ;This cleans up the stack. We pushed 5 things onto the stack each were 4 bytes long.
错了!您的代码在堆栈上只有 16 个字节。您在 pop esi
.
push esp
最后要显示单号结果,相应地更改格式字符串并使用:
msg2: db 'RESULT: %x ',10,0
...
mov eax, [inpt]
xor eax, ebx
push eax ;Push EAX to be printed
push msg2 ;Push the result print message
call _printf ;call the print function
add esp, 4
最后的建议:不要在程序中留下旧代码!您首先尝试使用硬编码数字 (0x70757573),然后切换到输入,但您没有删除一些之前相关的说明。这样做会产生一个包含多个错误的难以阅读的程序。
xor eax, eax ???
push eax ???
;push DWORD(0x70757573) ???
push inpt ???
push esp ???
pop esi ???
mov edi,esi ???
mov edx,edi ???
cld ???
mov ecx,0x80 ???
mov ebx,0x41
mov eax, inpt
xor eax,ebx
stosb ???
var1: dw 0x70757573 ;hex string to be XOR'd var2: db 0x41 ;Xor key to use
您将这些变量用作 dword 但您已将它们定义为 word 和 byte!
要么将它们重新定义为双字:
var1: dd 0x70757573 ;hex string to be XOR'd
var2: dd 0x41 ;Xor key to use
或更改使用它们的代码:
movzx eax, word [var1] ;Variable 1 to be XOR'd
movzx ebx, byte [var2] ;Variable 2, The key to xor var1 with
或两者都做:
var1: dd 0x70757573 ;hex string to be XOR'd
var2: db 0x41 ;Xor key to use
...
mov eax, [var1] ;Variable 1 to be XOR'd
movzx ebx, byte [var2] ;Variable 2, The key to xor var1 with