我将如何使其解密而不是加密? [英] How would i make this a decryption instead of an encryption?
问题描述
想知道如何从加密代码中获取密码,并使用相同的代码创建解密.
Wanna know how to get this from being a encryption code and using the same code to create a decryption.
我知道这意味着我必须反转一些指令并重新排序,但我无法弄清楚哪些指令需要重新排序,哪些不需要.
I know it means that I have to reverse some of the instruction and re-order it but I can't figure out which ones need to be reordered and which ones don't.
(edit)这是使事情变得更清晰的完整功能.堆栈溢出非常新,因此很抱歉造成任何混乱.
(edit) Heres the full function to make things a bit clearer. Very new to stack overflow so apologies for any confusions.
//---------------------------------------------------------------------------------------------------------------
//----------------- ENCRYPTION ROUTINES -------------------------------------------------------------------------
void decrypt_chars (int length, char EKey)
{
char temp_char; // Character temporary store
for (int i = 0; i < length; i++) // Encrypt characters one at a time
{
temp_char = OChars[i]; // Get the next char from Original Chars array
__asm
{
push eax // stores the "eax" register out onto the stack
push ecx // stores the "ecx" register out onto the stack
push edx // stores the "edx" register out onto the stack
//
movzx ecx, temp_char // zeroise "ecx" register and move values in "temp_char" varaible to "ecx" register
lea eax, EKey // copies address of values contained within the EKey varaible and moves it into "eax"register
//
push eax //
push ecx //
//
call decryptX // runs the function called "decryptX"
mov temp_char, dl // move values in "dl" register into "temp_char" variable
//
add esp, 8 //
pop edx // removes the "edx" register from the stack
pop ecx // removes the "ecx" register from the stack
pop eax // removes the "eax" register from the stack
} //
EChars[i] = temp_char; // store encrypted char in the Encrypted Chars array
}
return;
__asm
{
decryptX:
push ebp // stores the pointer onto the stack
mov ebp, esp // move values in "esp" register into "ebp" register
mov eax, [ebp + 12]// take value from the stack that is 8 bits above
// from the pointer a putting it in the "eax" register
mov ecx, [ebp + 8] // take value from the stack that is 8 bits above
// from the pointer a putting it on ecx
push eax // stores the Ekey address onto the stack
xchg eax, ecx // puts temp_char's value into the EKey address register and Ekey address into temp_char register
ror al, 1
ror al, 1
dec eax
neg al
mov ebx, eax // move temp_char value into "ebx" register
pop eax // removes temp_char from the stack
push ebx // stores temp_char value onto the stack
pop edx // removes "edx" register value from the stack
movzx ecx, [eax] // zeroise "ecx" register and move the address stored in "eax" register to "ecx" register
ror cl, 1 // rotate "cl" register value in bytes to the right by 1
xor cl, 0x96 // Exclusive OR (or XOR) the byte values within "cl" register with hex value 0x96 in binary
push ecx // stores the Ekey address onto the stack
and cl, 0x7 // AND the byte values within "cl" register with hex value 0x7 in binary
X: // Position X:
add dl, 2 // add 2 to value within dl
sub cl, 1 // subtract 1 from value within cl
jg X // jump to "X" position
pop ecx // removes "ecx" register value from the stack
xor ecx, edx // exclusive OR (or XOR) the byte values within "ecx" register with the byte values within "edx" register
mov[eax], cl // move "cl" register value into the address stored in "eax" register.
pop ebp // returning ebp back to the orginal value
ret // return, end of encryptX function
}
//--- End of Assembly code
}
//*** end of encrypt_chars function
//--------------------------------------------------------------------------------------------------------------
推荐答案
如果这是一项家庭作业,则实际上是一项非常棘手的任务. (尽管我可能忽略了一种简单的方法.)
If this is a homework assignment, then it's actually quite a tricky one. (Though I may have overlooked a simple approach.)
让我们集中讨论此代码对内存的影响.为简单起见,我假设您对这段代码对寄存器的影响不感兴趣,尽管我不确定在看到调用此函数的代码内.
Let's focus on the effect this code has on memory. For simplicity I will assume you are not interested in the effect this code has on registers, though I cannot be sure within seeing the code calling this function.
encryptL:
push eax
... ; ignoring this code because its effect on eax is undone by the following pop
pop eax
... ; code not affecting eax
movzx ecx, [eax]
... ; code not affecting eax
mov [eax], cl
ret
因此输入一个地址(eax
).该地址处的字节放入cl
,并且经过一些转换后,cl
被放回相同的地址.
我们需要弄清楚这些转换是什么,然后将其反转.
So in goes an address (eax
). The byte at this address is put into cl
, and after some transformations, cl
is put back at the same address.
We need to figure out what those transformations are, and invert those.
ror cl, 1
xor cl, 0x96
push ecx
... ; ignoring this code because its effect on ecx is undone by the following pop
pop ecx
xor ecx, edx
因此将一个旋转和两个xor应用于cl
.
Xor是 involution ,因此我们不必更改这两个指令.
rol
的倒数当然是ror
,尽管并非完全如此.进位标志的作用不能反转,但是在这种情况下,该作用被忽略,所以我们很好.
So a rotate and two xors are applied to cl
.
Xor is an involution, so we do not have to change those two instructions.
The inverse of rol
is of course ror
, though that is not entirely true. The effect on the carry flag cannot be inverted, but in this case that effect is ignored, so we are good.
但是我们忽略的所有代码呢?仔细检查后,您会发现只有在这里可以计算xor ecx,edx
中使用的edx
的值.
不幸的是,[eax]
的原始(未加密)值涉及该计算.
解密时,原始值即为最终值,即xor ecx,edx
的结果.
我们似乎遇到了鸡和蛋的问题.取决于相同计算结果时如何执行计算?
But what about all the code we ignored? On close inspection, you'll notice it is only there to calculate the value of edx
that is used in xor ecx,edx
.
Unfortunately, the original (unencrypted) value of [eax]
is involved in that calculation.
When decrypting, the original value becomes the final value, i.e. the result of xor ecx,edx
.
We seem to have a chicken-and-egg problem. How to perform the calculation when it depends on the result of that same calculation?
由于以下陈述,很显然,[eax]
对edx
的计算的影响是8种可能情况中的1种:
It should be clear that the effect of [eax]
on the calculation of edx
, is either 1 out of only 8 possible cases, due to this statement:
and cl, 0x7
这意味着我们可以使用循环来尝试所有不同的可能性,直到找到一个计算结果与在[eax]
中找到的值匹配的值为止.
该循环与加密器中的该循环非常相似:
That means we can use a loop to try all different possibilities, until we found one where the result of the calculation matches the value we found in [eax]
.
That loop will be very similar to this loop found in the encryptor:
X:
add dl, 2
sub cl, 1
jg X
但是,循环的退出条件将有所不同.
However, the exit condition of the loop will be different.
mov bl,0 ; using bl as a loop counter (similar to cl in original loop)
X:
inc bl
add dl,2 ; same as in the original loop
mov cl,[eax] ; fetch encrypted byte from memory
xor ecx,edx ; try transforming cl with the current value of dl
xor ebx,ecx ; compare cl with the loop counter (bl)
and bl,7 ; only compare the 3 least significant bits
jg X ; if not zero, try again with the next possible value of dl
由于xor
是可交换和关联的,因此我们可以重写此代码.
而不是递增bl
直到与cl
匹配,我们将递减cl
直到其(部分)转换后的值为零(模8).
Since xor
is commutative and associative, we can rewrite this code.
Instead of incrementing bl
until it matches cl
, we will decrement cl
until its (partially) transformed value is zero (modulo 8).
mov cl,[eax] ; fetch encrypted byte from memory
X:
add dl,2 ; same as in the original loop
sub cl,1 ; same as in the original loop
push ecx
xor ecx,edx ; transform cl with the current value of dl
and cl,7 ; only consider the 3 least significant bits
pop ecx ; restore cl (without clobbering flags)
jg X ; if equal, then we found the right starting point
对于其余的代码,可以保持原样.在[eax]
涉及之前,它主要是edx
的计算的初始部分.
As for the rest of the code, that can stay as it is. It is mainly the initial part of the calculation of edx
, before [eax]
becomes involved.
这是完整的解决方案:
encryptL:
push eax
xchg eax, ecx
neg al
inc eax
rol al, 1
rol al, 1
mov ebx, eax
pop eax
push ebx
pop edx
movzx ecx, [eax]
push ecx
X:
add dl,2
sub cl,1
push ecx
xor ecx,edx
and cl,7
pop ecx
jg X
pop ecx
xor ecx,edx
xor cl,0x96
rol cl,1
mov [eax],cl
ret
免责声明:我没有对其进行测试,因此很有可能无法正常工作.我将把调试工作留给您.
Disclaimer: I did not test it, so it's quite likely it will not work. I will leave the debugging up to you.
这篇关于我将如何使其解密而不是加密?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!