再贴一个使用类似方法的内存注册机, (5千字)
一年多以前写的,针对版本有些老(好像是2.4-3.0),新版的算法分析论坛里有,只作方法演示用,代码中使用了特征代码查询方式,以适应版本更新,只要算法不变,可以用在不同版本上。该软件在计算注册码时分为两部分,前一部分比较简单,后一部分很复杂,但只要使用后一部分算出来的结果根据前一部分的计算逻辑,很容易就可以算出注册码。
// cr-cglc.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
unsigned int decode(unsigned int num);
LPBYTE search(LPBYTE pbuff, int oSize, LPBYTE sub, int subSize)
{
for (int i = 0; i < oSize - subSize; i++, pbuff++)
{
if (*pbuff == *sub)
{
if (memcmp(pbuff, sub, subSize) == 0)
return pbuff;
}
}
return NULL;
}
#define BUFF_SIZE 1024 * 1024
int main(int argc, char* argv[])
{
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
"mygp.exe", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
printf( "CreateProcess failed." );
return 0;
}
WaitForInputIdle(pi.hProcess, INFINITE);
// 定义特征代码
unsigned char orig1[] = {0x8b, 0xc6, 0x01, 0x55, 0x88};
unsigned char orig2[] = {0x29, 0x45, 0x88, 0x8d, 0x45, 0xfc};
unsigned char orig3[] = {0x29, 0x45, 0x88, 0x83, 0x7d, 0x88, 0x00};
unsigned char buff1[5], buff2[6], buff3[7];
DWORD bytes;
LPBYTE lpbase = LPBYTE(0x401000);
LPBYTE pbuff = new BYTE[BUFF_SIZE];
// 读取待扫描区域,这里只使用了简单的读定长数据,
BOOL bok = ReadProcessMemory(pi.hProcess,
lpbase, pbuff, BUFF_SIZE, &bytes);
if (!bok)
{
delete pbuff;
return 0;
}
// 扫描特征码
lpbase = search(pbuff, BUFF_SIZE, orig1, sizeof(orig1));
// 判断找到的位置是否正确
if (lpbase == NULL ||
memcmp(lpbase + 10, orig2, sizeof(orig2)) != 0 ||
memcmp(lpbase + 21, orig3, sizeof(orig3)) != 0)
{
delete pbuff;
printf("regcode not found.");
TerminateProcess(pi.hProcess, -1);
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return 0;
}
lpbase = (LPBYTE)0x401000 + (lpbase - pbuff);
LPBYTE lpbase1 = lpbase;
LPBYTE lpbase2 = lpbase + 10;
LPBYTE lpbase3 = lpbase + 21;
delete pbuff;
bok = ReadProcessMemory(pi.hProcess,
lpbase1, buff1, sizeof(buff1), &bytes);
if (memcmp(buff1, orig1, sizeof(buff1)) == 0)
{
buff1[0] = 0xcc;
WriteProcessMemory(pi.hProcess,
lpbase1, buff1, sizeof(buff1), &bytes);
}
bok = ReadProcessMemory(pi.hProcess,
lpbase2, buff2, sizeof(buff2), &bytes);
// 设置断点1
if (memcmp(buff2, orig2, sizeof(buff2)) == 0)
{
buff2[0] = 0xcc;
WriteProcessMemory(pi.hProcess,
lpbase2, buff2, sizeof(buff2), &bytes);
}
bok = ReadProcessMemory(pi.hProcess,
lpbase3, buff3, sizeof(buff3), &bytes);
// 设置断点2
if (memcmp(buff3, orig3, sizeof(buff3)) == 0)
{
buff3[0] = 0xcc;
WriteProcessMemory(pi.hProcess,
lpbase3, buff3, sizeof(buff3), &bytes);
}
// 进入调试状态
bok = DebugActiveProcess(pi.dwProcessId);
DEBUG_EVENT dbg = {0};
unsigned int x, y, z;
CONTEXT context = {0};
while (WaitForDebugEvent(&dbg, INFINITE))
{
if (dbg.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
{
if (dbg.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
{
if (dbg.u.Exception.ExceptionRecord.ExceptionAddress == lpbase1)
{
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (GetThreadContext(pi.hThread, &context))
{
context.Eip--;
WriteProcessMemory(pi.hProcess,
lpbase1, orig1, sizeof(orig1), &bytes);
SetThreadContext(pi.hThread, &context);
bok = ReadProcessMemory(pi.hProcess,
LPVOID(context.Ebp - 0x78), &x, sizeof(x), &bytes);
}
}
else if (dbg.u.Exception.ExceptionRecord.ExceptionAddress == lpbase2)
{
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (GetThreadContext(pi.hThread, &context))
{
context.Eip--;
WriteProcessMemory(pi.hProcess,
lpbase2, orig2, sizeof(orig2), &bytes);
SetThreadContext(pi.hThread, &context);
y = context.Eax;
}
}
else if (dbg.u.Exception.ExceptionRecord.ExceptionAddress == lpbase3)
{
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (GetThreadContext(pi.hThread, &context))
{
context.Eip--;
WriteProcessMemory(pi.hProcess,
lpbase3, orig3, sizeof(orig3), &bytes);
SetThreadContext(pi.hThread, &context);
z = context.Eax;
printf("Your Register Code is:\n");
// 计算注册码
printf("%08X\n", decode(y + z - x));
}
}
}
}
else if (dbg.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
break;
bok = ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
unsigned int decode(unsigned int num)
{
_asm {
mov ebx, 3
mov ecx, num
xor ecx, 0x81079516
start:
mov dh, cl
mov dl, ch
shl dx, 7
mov al, dh
ror eax, 8
ror ecx, 8
mov dh, cl
mov dl, ch
shl dx, 7
mov al, dh
shr ecx, 8
mov dh, cl
mov dl, ch
shl dx, 7
mov ah, dh
ror eax, 16
shr ecx, 8
mov dh, cl
mov dl, ch
shl dx, 7
mov al, dh
dec ebx
jz end
mov ecx, eax
jmp start
end:
}
}
