xor 不同长度的十六进制字符串 NASM

xor hex strings of different length NASM

我正在试验基本的 XOR 函数,我正在尝试对用户输入的十六进制字符串进行异或运算,即 0x43424143 针对 0x41.

的键

我编写了有效的代码,但我对返回的一些奇怪结果有点好奇。下面编写的代码用于 NASM,它将在 Windows 上编译和 运行(我正在使用外部 C 库函数 scanfprintf)。

我有几个版本,一个以十六进制字符串作为输入,另一个是硬编码的,第二个版本只是为了让事情简单化,同时弄清楚其他一些事情。

两个版本都给出了相同的奇怪输出,我很确定这是错误的。我只是很好奇我是否遗漏了任何明显的事情,我仍然是一个装配和逆向工程方面的大菜鸟。这有点晦涩,所以如果没有明显的地方我出错了,那么我会很高兴地继续研究它,直到找到问题所在。

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 但您已将它们定义为 wordbyte!

要么将它们重新定义为双字:

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