高级到 ASM 转换
High Level to ASM conversion
我正在学习汇编编程,我的任务是在我的程序中将 for 循环(以及任何数组使用)转换为汇编。
该程序只需要一个加密密钥 (EKey
) 并使用它来加密一组字母(例如 hello
)。
这是 C++ 中的循环:
void encrypt_chars(int length, char EKey)
{
char temp_char; // char temporary store
for (int i = 0; i < length; i++) // encrypt characters one at a time
{
temp_char = OChars[i]; // temp_char now contains the address values of the individual character
__asm
{
push eax // Save values contained within register to stack
push ecx
movzx ecx, temp_char
push ecx // Push argument #2
lea eax, EKey
push eax // Push argument #1
call encrypt
add esp, 8 // Clean parameters of stack
mov temp_char, al // Move the temp character into a register
pop ecx
pop eax
}
EChars[i] = temp_char; // Store encrypted char in the encrypted chars array
}
return;
// Inputs: register EAX = 32-bit address of Ekey,
// ECX = the character to be encrypted (in the low 8-bit field, CL).
// Output: register EAX = the encrypted value of the source character (in the low 8-bit field, AL).
__asm
{
encrypt:
push ebp // Set stack
mov ebp, esp // Set up the base pointer
mov eax, [ebp + 8] // Move value of parameter 1 into EAX
mov ecx, [ebp + 12] // Move value of parameter 2 into ECX
push edi // Used for string and memory array copying
push ecx // Loop counter for pushing character onto stack
not byte ptr[eax] // Negation
add byte ptr[eax], 0x04 // Adds hex 4 to EKey
movzx edi, byte ptr[eax] // Moves value of EKey into EDI using zeroes
pop eax // Pop the character value from stack
xor eax, edi // XOR character to give encrypted value of source
pop edi // Pop original address of EDI from the stack
rol al, 1 // Rotates the encrypted value of source by 1 bit (left)
rol al, 1 // Rotates the encrypted value of source by 1 bit (left) again
add al, 0x04 // Adds hex 4 to encrypted value of source
mov esp, ebp // Deallocate values
pop ebp // Restore the base pointer
ret
}
//--- End of Assembly code
}
我查看了反汇编代码并用它来重写 ASM 代码。我按如下方式输入反汇编代码,但出现以下错误:http://gyazo.com/3b6875c9e1207df61df4e95506af7ed6
这是我的代码:
void encrypt_chars(int length, char EKey)
{
char temp_char;
__asm
{
mov DWORD PTR[rbp - 4], 0
jmp L2
L3:
mov eax, DWORD PTR[rbp - 4]
cdqe
cltq
// ERROR HERE ^ above: error C2400: inline assembler syntax error in 'opcode'; found 'newline'
movzx eax, BYTE PTR EChars[rax]
// ERROR HERE ^ above: error C2400: inline assembler syntax error in 'opcode'; found 'newline'
// another error ^ above: error C2424: '[' : improper expression in 'second operand'
mov BYTE PTR[rbp - 5], al
// OG code
push eax // Save values contained within register to stack
push ecx
movzx ecx, temp_char
push ecx // Push argument #2
lea eax, EKey
push eax // Push argument #1
call encrypt4
add esp, 8 // Clean parameters of stack
mov temp_char, al // Move the temp character into a register
pop ecx
pop eax
// end of OG code
mov eax, DWORD PTR[rbp - 4]
cdqe
movzx edx, BYTE PTR[rbp - 5] // ERROR HERE: error C2400: inline assembler syntax error in 'opcode'; found 'newline'
mov BYTE PTR DChars[rax], dl // ERROR HERE: error C2424: '[' : improper expression in 'first operand'
L2:
mov eax, DWORD PTR[rbp - 4]
cmp eax, DWORD PTR[rbp - 20]
jl L3
}
return;
__asm
{
encrypt4:
push ebp // Set stack
mov ebp, esp // Set up the base pointer
mov eax, [ebp + 8] // Move value of parameter 1 into EAX
mov ecx, [ebp + 12] // Move value of parameter 2 into ECX
push edi // Used for string and memory array copying
push ecx // Loop counter for pushing character onto stack
not byte ptr[eax] // Negation
add byte ptr[eax], 0x04 // Adds hex 4 to EKey
movzx edi, byte ptr[eax] // Moves value of EKey into EDI using zeroes
pop eax // Pop the character value from stack
xor eax, edi // XOR character to give encrypted value of source
pop edi // Pop original address of EDI from the stack
rol al, 1 // Rotates the encrypted value of source by 1 bit (left)
rol al, 1 // Rotates the encrypted value of source by 1 bit (left) again
add al, 0x04 // Adds hex 4 to encrypted value of source
mov esp, ebp // Deallocate values
pop ebp // Restore the base pointer
ret
}
//--- End of Assembly code
}
有人能指出我哪里错了吗?我发现这相对困难,因此非常欢迎逐步解释。请让我知道我哪里出错了。谢谢 x
编辑:
我的完整代码:http://pastebin.com/tP9Dgvpn
试试这个:
void encrypt_chars(int length, char EKey, char *Msg)
{
int InLength = length;
int counter;
__asm
{
push eax // Counter
mov eax, 0 // Zero counter
push ebx // Value
mov ebx, InLength
jmp L2
L3:
mov counter, EAX
call encrypt4
inc eax // Increment counter.
L2:
cmp eax, ebx
jl L3 // Jump if we haven't reached our count.
pop ebx
pop eax
}
return;
__asm
{
encrypt4:
push eax
push ebx
push edi
mov ebx, counter
add ebx, Msg
mov al, [ebx] // Move character into al
CBW // Make word.
CWDE // Make Dword.
not byte ptr[EKey] // Negation
add byte ptr[EKey], 0x04 // Adds hex 4 to EKey
movzx edi, byte ptr[EKey] // Moves value of EKey into EDI using zeroes
xor eax, edi // XOR character to give encrypted value of source
pop edi // Pop original address of EDI from the stack
rol al, 1 // Rotates the encrypted value of source by 1 bit (left)
rol al, 1 // Rotates the encrypted value of source by 1 bit (left) again
add al, 0x04 // Adds hex 4 to encrypted value of source
mov [ebx], al
pop ebx
pop eax
ret
}
//--- End of Assembly code
}
我用这段代码调用它:
EKey = 'i';
sprintf(OChars, "hello");
printf("%s\n", OChars);
encrypt_chars(sizeof(OChars), EKey, OChars);
printf("%s\n", OChars);
我的输出如下所示:
你好
╧4▀↑█⌐
这与您的输出相匹配,但除了第一个字符。我确信算法看起来是正确的,我不能再花时间在上面了。我相信这可能是字符集的差异。试试吧。
祝你好运!
我正在学习汇编编程,我的任务是在我的程序中将 for 循环(以及任何数组使用)转换为汇编。
该程序只需要一个加密密钥 (EKey
) 并使用它来加密一组字母(例如 hello
)。
这是 C++ 中的循环:
void encrypt_chars(int length, char EKey)
{
char temp_char; // char temporary store
for (int i = 0; i < length; i++) // encrypt characters one at a time
{
temp_char = OChars[i]; // temp_char now contains the address values of the individual character
__asm
{
push eax // Save values contained within register to stack
push ecx
movzx ecx, temp_char
push ecx // Push argument #2
lea eax, EKey
push eax // Push argument #1
call encrypt
add esp, 8 // Clean parameters of stack
mov temp_char, al // Move the temp character into a register
pop ecx
pop eax
}
EChars[i] = temp_char; // Store encrypted char in the encrypted chars array
}
return;
// Inputs: register EAX = 32-bit address of Ekey,
// ECX = the character to be encrypted (in the low 8-bit field, CL).
// Output: register EAX = the encrypted value of the source character (in the low 8-bit field, AL).
__asm
{
encrypt:
push ebp // Set stack
mov ebp, esp // Set up the base pointer
mov eax, [ebp + 8] // Move value of parameter 1 into EAX
mov ecx, [ebp + 12] // Move value of parameter 2 into ECX
push edi // Used for string and memory array copying
push ecx // Loop counter for pushing character onto stack
not byte ptr[eax] // Negation
add byte ptr[eax], 0x04 // Adds hex 4 to EKey
movzx edi, byte ptr[eax] // Moves value of EKey into EDI using zeroes
pop eax // Pop the character value from stack
xor eax, edi // XOR character to give encrypted value of source
pop edi // Pop original address of EDI from the stack
rol al, 1 // Rotates the encrypted value of source by 1 bit (left)
rol al, 1 // Rotates the encrypted value of source by 1 bit (left) again
add al, 0x04 // Adds hex 4 to encrypted value of source
mov esp, ebp // Deallocate values
pop ebp // Restore the base pointer
ret
}
//--- End of Assembly code
}
我查看了反汇编代码并用它来重写 ASM 代码。我按如下方式输入反汇编代码,但出现以下错误:http://gyazo.com/3b6875c9e1207df61df4e95506af7ed6
这是我的代码:
void encrypt_chars(int length, char EKey)
{
char temp_char;
__asm
{
mov DWORD PTR[rbp - 4], 0
jmp L2
L3:
mov eax, DWORD PTR[rbp - 4]
cdqe
cltq
// ERROR HERE ^ above: error C2400: inline assembler syntax error in 'opcode'; found 'newline'
movzx eax, BYTE PTR EChars[rax]
// ERROR HERE ^ above: error C2400: inline assembler syntax error in 'opcode'; found 'newline'
// another error ^ above: error C2424: '[' : improper expression in 'second operand'
mov BYTE PTR[rbp - 5], al
// OG code
push eax // Save values contained within register to stack
push ecx
movzx ecx, temp_char
push ecx // Push argument #2
lea eax, EKey
push eax // Push argument #1
call encrypt4
add esp, 8 // Clean parameters of stack
mov temp_char, al // Move the temp character into a register
pop ecx
pop eax
// end of OG code
mov eax, DWORD PTR[rbp - 4]
cdqe
movzx edx, BYTE PTR[rbp - 5] // ERROR HERE: error C2400: inline assembler syntax error in 'opcode'; found 'newline'
mov BYTE PTR DChars[rax], dl // ERROR HERE: error C2424: '[' : improper expression in 'first operand'
L2:
mov eax, DWORD PTR[rbp - 4]
cmp eax, DWORD PTR[rbp - 20]
jl L3
}
return;
__asm
{
encrypt4:
push ebp // Set stack
mov ebp, esp // Set up the base pointer
mov eax, [ebp + 8] // Move value of parameter 1 into EAX
mov ecx, [ebp + 12] // Move value of parameter 2 into ECX
push edi // Used for string and memory array copying
push ecx // Loop counter for pushing character onto stack
not byte ptr[eax] // Negation
add byte ptr[eax], 0x04 // Adds hex 4 to EKey
movzx edi, byte ptr[eax] // Moves value of EKey into EDI using zeroes
pop eax // Pop the character value from stack
xor eax, edi // XOR character to give encrypted value of source
pop edi // Pop original address of EDI from the stack
rol al, 1 // Rotates the encrypted value of source by 1 bit (left)
rol al, 1 // Rotates the encrypted value of source by 1 bit (left) again
add al, 0x04 // Adds hex 4 to encrypted value of source
mov esp, ebp // Deallocate values
pop ebp // Restore the base pointer
ret
}
//--- End of Assembly code
}
有人能指出我哪里错了吗?我发现这相对困难,因此非常欢迎逐步解释。请让我知道我哪里出错了。谢谢 x
编辑:
我的完整代码:http://pastebin.com/tP9Dgvpn
试试这个:
void encrypt_chars(int length, char EKey, char *Msg)
{
int InLength = length;
int counter;
__asm
{
push eax // Counter
mov eax, 0 // Zero counter
push ebx // Value
mov ebx, InLength
jmp L2
L3:
mov counter, EAX
call encrypt4
inc eax // Increment counter.
L2:
cmp eax, ebx
jl L3 // Jump if we haven't reached our count.
pop ebx
pop eax
}
return;
__asm
{
encrypt4:
push eax
push ebx
push edi
mov ebx, counter
add ebx, Msg
mov al, [ebx] // Move character into al
CBW // Make word.
CWDE // Make Dword.
not byte ptr[EKey] // Negation
add byte ptr[EKey], 0x04 // Adds hex 4 to EKey
movzx edi, byte ptr[EKey] // Moves value of EKey into EDI using zeroes
xor eax, edi // XOR character to give encrypted value of source
pop edi // Pop original address of EDI from the stack
rol al, 1 // Rotates the encrypted value of source by 1 bit (left)
rol al, 1 // Rotates the encrypted value of source by 1 bit (left) again
add al, 0x04 // Adds hex 4 to encrypted value of source
mov [ebx], al
pop ebx
pop eax
ret
}
//--- End of Assembly code
}
我用这段代码调用它:
EKey = 'i';
sprintf(OChars, "hello");
printf("%s\n", OChars);
encrypt_chars(sizeof(OChars), EKey, OChars);
printf("%s\n", OChars);
我的输出如下所示: 你好
╧4▀↑█⌐
这与您的输出相匹配,但除了第一个字符。我确信算法看起来是正确的,我不能再花时间在上面了。我相信这可能是字符集的差异。试试吧。
祝你好运!