[转载]Self Modifying Codes:A Pinch of XOR
文章作者:kka_kennyThis archive contains:
files.rar - Contains original & crypted crackme examples
xor.txt - Contains the code
paper.pdf - This paper
bconv32.exe - Number System Converter
Introduction:
Self modifying codes are not as hard as people think it is. Whilst some people think it is such great amazements I couldn't imagine other people whose less informed about technology. If they thought I LOVE YOU Bug virus was amazing how much more can they think of self modifying codes. Back in the day this was a big highlight I use to see vx writers (assembly writers only) as gods when I read all those paper & zines they released and try to read those lines of asm codes even though I don't understand it. Not only vx writers, anti-cracking companies also does self modifying codes which in my understanding was inherited from our dear anti-social vx writers as well. I wouldnt consider all of them anti social though as not all of them has the intent of "vxing dah whole world", I have high respects for such people, people with the desire of attaining high level knowledge against all odds, as we all are in different communities in the computer underground.
Self modifying codes are normally done using bitwise operators such as XOR (commonly) and other encryption OP's. Now to tell you the truth I am not an expert on this nor do I code self modifying codes as much but I do like observing them, learning from them and reversing them. I have to say for all those wishing to write such codes, the lower the language the easier it is as it is closer to our dear machine codes, if you can program in pure binary then so be it :-).
The Paper:
Right getting on to what our aim is, I'll tell you a story about self modifying codes. First of there was the real bytes and from the real bytes the numbers were taken by bitwise operator XOR, XOR decides to juggle them around until the condition was meet, the practice was for XOR to rewrite the code until the code is equal to what was expected. When the conditions was met XOR then jumps to the real instructions where the real action happens.
We will be dealing with XOR as it is the most common operator used and is after all the most suitable for the job. For those starting it, I will show you a simple explanation of XOR
Exclusive-OR known as XOR sets the output bit to1 if the two given numbers are not the same, so in binary terms its as simple as this
0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0
Right let's do that in something we actually use
mov src,dest
mov src,dest
xor src,dest
mov eax,15h
mov ebx,10h
xor eax,ebx
Using Bcon32 (together w/ the archive) we will convert the hex numbers to binary, h at the end of the numbers tells us that it is Hex else it is decimal.
EAX = 00010101
EBX = 00010000
XOR 00010101, 00010000
output becomes
00000101
Output is now the new value of EAX because it is the destination, convert that back to hex if you wish to see the result but sadly our converter doesnt have this function. (there are tons which has otherwise use pen and paper ;-)
I hope the XOR explanation was clear to you, there are tons of ways in which you can use xor as your encryptor this is just my version of it:
-------------------------CODE-------------------------
main:
mov register1,value1 ;address to overwrite
mov register2,value2 ;lower address
mov register3,value3 ;high address
xor register1,hex ;any hex to overwrite
inc register2 ;increment address2
dec register3 ;decrement address3
cmp register2,register3 ;compare both registers
je push ;if equal then jump to push
inc register1 ;increment register1
jmp xor routine ;jump back to xor
push:
push OEP address
ret
btw you can also change it to something like
push:
mov ebx,OEP address
jmp EBX
or whatever your normal thing is, it depends on what you are used to.
-------------------------CODE-------------------------
Thats it, simple? of course it is, if you still didnt get that then i'm freaking killing myself thats commented to the bones. If you still dont get that then I suggest you stop reading and read something even more basic (if there is something as such). Looking at that code above now you can make your own simple self modifying engine, thats not the engine code but thats the code that is going to be embedded to our program you wish to encrypt.
Together in the archive are 2 crackme file both the same but the other one is self modifying. This is the code I embedded into it, I changed the entry point which was 00401088 to 0040396C where my code cave was. Afterwhich I placed the code which then jumps back to the OEP
-------------------------CODE-------------------------
0040396C > $ B8 00104000 MOV EAX,beta.00401000 ; Entry address
00403971 . BB 00104000 MOV EBX,beta.00401000 ; Entry address
00403976 . B9 6A394000 MOV ECX,beta.0040396A
0040397B 8030 3F XOR BYTE PTR DS:[EAX],3F
0040397E . 43 INC EBX
0040397F . 49 DEC ECX
00403980 . 3BD9 CMP EBX,ECX
00403982 . 74 03 JE SHORT beta.00403987
00403984 . 40 INC EAX
00403985 .^EB F4 JMP SHORT beta.0040397B
00403987 > B8 6A394000 MOV EAX,beta.0040396A
0040398C . BB 00104000 MOV EBX,beta.00401000 ; Entry address
00403991 . B9 6A394000 MOV ECX,beta.0040396A
00403996 8030 3F XOR BYTE PTR DS:[EAX],3F
00403999 . 43 INC EBX
0040399A . 49 DEC ECX
0040399B . 3BD9 CMP EBX,ECX
0040399D . 74 03 JE SHORT beta.004039A2
0040399F . 48 DEC EAX
004039A0 .^EB F4 JMP SHORT beta.00403996
004039A2 > 68 88104000 PUSH beta.00401088
004039A7 . C3 RETN ; RET used as a jump to 00401088
-------------------------CODE-------------------------
If you look at it its fairly similar to the one I showed you awhile ago. It's not easy to explain on how I placed that to the executable, well actually it is just write the codes and using a PE Editor like LordPE change the entry point to our code cave and thats it. Explaining this code would be useless I'd suggest open up the exe file in a debugger instead and observe.
I used ollydbg as my debugger to observe what is going on, the old file which was not crypted looks like this basically
-------------------------CODE-------------------------
00401088 >/$ 55 PUSH EBP
00401089 |. 8BEC MOV EBP,ESP
0040108B |. 6A FF PUSH -1
0040108D |. 68 A0404000 PUSH original.004040A0
00401092 |. 68 BC1B4000 PUSH original.00401BBC ; SE handler installation
00401097 |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0040109D |. 50 PUSH EAX
0040109E |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
004010A5 |. 83EC 58 SUB ESP,58
004010A8 |. 53 PUSH EBX
004010A9 |. 56 PUSH ESI
004010AA |. 57 PUSH EDI
004010AB |. 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
004010AE |. FF15 14404000 CALL DWORD PTR DS:[<&KERNEL32.GetVersion>; kernel32.GetVersion
004010B4 |. 33D2 XOR EDX,EDX
004010B6 |. 8AD4 MOV DL,AH
004010B8 |. 8915 24554000 MOV DWORD PTR DS:[405524],EDX
004010BE |. 8BC8 MOV ECX,EAX
004010C0 |. 81E1 FF000000 AND ECX,0FF
004010C6 |. 890D 20554000 MOV DWORD PTR DS:[405520],ECX
004010CC |. C1E1 08 SHL ECX,8
004010CF |. 03CA ADD ECX,EDX
004010D1 |. 890D 1C554000 MOV DWORD PTR DS:[40551C],ECX
004010D7 |. C1E8 10 SHR EAX,10
004010DA |. A3 18554000 MOV DWORD PTR DS:[405518],EAX
-------------------------CODE-------------------------
Now the crypted file looks like this at the same addresses
-------------------------CODE-------------------------
00401088 6A DB 6A ; CHAR 'j'
00401089 B4 DB B4
0040108A D3 DB D3
0040108B 55 DB 55 ; CHAR 'U'
0040108C C0 DB C0
0040108D 57 DB 57 ; CHAR 'W'
0040108E 9F DB 9F
0040108F 7F DB 7F
00401090 7F DB 7F
00401091 3F DB 3F ; CHAR '?'
00401092 57 DB 57 ; CHAR 'W'
00401093 83 DB 83
00401094 24 DB 24 ; CHAR '$'
00401095 7F DB 7F
00401096 3F DB 3F ; CHAR '?'
00401097 5B DB 5B ; CHAR '['
00401098 9E DB 9E
OR
00401088 6A B4 PUSH -4C
0040108A D355 C0 RCL DWORD PTR SS:[EBP-40],CL
0040108D 57 PUSH EDI
0040108E 9F LAHF
0040108F 7F 7F JG SHORT crypt.00401110
00401091 3F AAS
00401092 57 PUSH EDI
00401093 83247F 3F AND DWORD PTR DS:[EDI+EDI*2],3F
00401097 5B POP EBX
00401098 9E SAHF
00401099 3F AAS
0040109A 3F AAS
0040109B 3F AAS
0040109C 3F AAS
0040109D 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O command
0040109E 5B POP EBX
0040109F B6 1A MOV DH,1A
004010A1 3F AAS
004010A2 3F AAS
004010A3 3F AAS
004010A4 3F AAS
004010A5 BC D3676C69 MOV ESP,696C67D3
004010AA 68 B65AD7C0 PUSH C0D75AB6
-------------------------CODE-------------------------
Conclusion:
I think we all know what the benefits of this is to us, try opening it up in a disassembler like W32DASM or IDA or a Hex Editor and you'll just see the fucked up codes, now this is an advantage for detected malwares because it can crypt the signature string therefore making it undetected. It can also be used as an anti-cracking tactic because it hides all the text string etc until it is decrypted. However I doubt if this will work with an average reverser any how. The whole point is this is still simple and can be developed. You can try to develop by adding simple code shifting or api redirections etc. this is just a simple introduction boys and girls, welcome to self modifying behaviour.
Have phun with your new found knowledge. Dont forget to spread the word, learn your own words and spread it the same way.
Good day,
页:
[1]
