Token "to generate a registration code for registration.
For example:
MyNameIsMrWrong
Bytes
MrWrong
Bytes
Code Development Environment: win7 x64 sp1
The program is not completely analyzed as follows: 1. Take off the compression shell to facilitate analysis.
2. After shelling, the analysis found that the following code is available:
If (CreateMutexW (0, 0, Name) {if (GetLastError () = 0xB7) {CreateThread (0, 0, sub_401BC0, 0, 0, 0 ); // create a thread. A thread is also created in the thread to decrypt part of the code used for verification.} else // is the first instance, run your own copy {Filename = 0; memset (& v10, 0, 0x206u); memset (& StartupInfo. lpReserved, 0, 0x40u); StartupInfo. cb = 68; GetModuleFileNameW (0, & Filename, 0x208u); if (CreateProcessW (& Filename, 0, 0, 0, 0, 1u, 0, 0, & StartupInfo, & ProcessInformation) {DebugEvent. dwDebugEventCode = 0; memset (& DebugEvent. dwProcessId, 0, 0x5Cu); while (WaitForDebugEvent (& DebugEvent, 0 xFFFFFFFF) {if (DebugEvent. dwDebugEventCode = 8) // debug the copy in one step until the copy outputs a DebugString break; ContinueDebugEvent (DebugEvent. dwProcessId, DebugEvent. dwThreadId, 0x10002u);} DebugSetProcessKillOnExit (0); DebugActiveProcessStop (ProcessInformation. dwProcessId); ExitProcess (0 );}}}
3. Some codes used for verification are encrypted through the crc32 check and hash value of the file. If the file is changed, it cannot be decrypted correctly. After correct decryption, call VirtualProtect at address 00541702 and modify this segment to dynamically apply for PAGE_EXECUTE_READWRITE memory.
Permission. I am not planning to modify any data in the program before that, so I am not worried about this.
4. the decrypted code analysis (registration code verification process ):
(1) The registration code is all numbers. After A string is combined into two strings, it is recorded as "A", perform base64 decryption on A (the base64 decryption function is 0x1000 offset from the dynamically applied memory, recorded as sub_off_1000). After base64 decryption, the obtained data is recorded as "B".
(2) "B" will be decrypted using the sub_off_1A90 function to obtain "C". The private key "lingdux_keygen" is used internally, which is a 512-bit encryption/Decryption Method, however, I have not figured out what algorithm this decryption function is. I only suspect that it is AES512 (the Registration machine that cannot fix the hook cannot give it ).
(3) Calculate the MD5 value of the Username string as "D ".
(4) For "C", the following relationships must be met.
C[0] == D[0];C[1] == D[2];C[2] == D[4];C[3] == D[6];C[5] == D[8];C[6] == D[10];C[7] == D[12];C[8] == D[14];
(5) use the sub_off_1DD0 + key "lingdux" function to decrypt a binary string (as "Q") and obtain the fixed string: "Success". because the sub_off_1A90 function is not clear, the idea of writing a registration machine is disheartened and busy at work, no matter where he is.
But this "Q" must have been transformed from the rest of "C.
(6) Calculate the MD5 value of the string "Success" and obtain the binary sequence: 505a83f220c02df2f85c3810cd9ceb38, and compare it with the binary sequence stored in the program. If not, you will lose one cent.
If the Registrar cannot do this, it will HOOK the unknown places into known ones.
As follows:
Int _ stdcall hook_off_1a90 (void) {BYTE * p; // [in] & [out] _ asm {mov p, ecx} // when you are on the registration machine, data in p can be encrypted. I have not encrypted the data and it cannot be blocked. // Some_encrypt (p, 64); return 1 ;}
There is also a hook for the time of hook_off_1a90, that is, when you are about to call part of the "Verification Code" above.
Authorization; DWORD _ stdcall parameters (LPVOID lpThreadParameter) 00401A20 lpThreadParameter = dword ptr pushed offset when call done // add esp, 400401A2E xor eax, limit retn 400401A30 StartAddress endp
The hook source code is as follows:
int __stdcall hook_5b40a0(int np){ _asm { pushad pushfd } static BOOL patched = FALSE; if(!patched) { patched = TRUE; DWORD addr = (DWORD)g_5b40a0 - 0x1F20 + 0x2167 + 1; DWORD call_offset = (DWORD)hook_off_1a90 - addr - 4; *(DWORD*)addr = call_offset; //hooked hook_off_1a90 } _asm { popfd popad } int ret = g_5b40a0(np); return ret;}
The other parts are the same as those of the original registration algorithm. The method is used only in the unknown, and the unknown is changed to known.
If the time is limited, the remote injection tool uses the classic tool named remotedll.exe ".
You have no trouble in learning the ocean. Please forgive us for your mistakes.
By: MrWrong mailbox: rongguozhen@foxmail.com 20140428
File: http://www.2cto.com/uploadfile/2014/0518/20140518033453804.rar