📄 crackme.cpp
字号:
}
// --------------------------------------------
// Now I've the process ID then I can attach it
// --------------------------------------------
if (DebugActiveProcess(aVictimProcessId) == 0)
{
MessageBox(NULL, "\tFailed to attach the process!", szMsgCapt, MB_OK);
if (hPsapi != NULL)
FreeLibrary(hPsapi);
return ;
}
else
{
if (bDebugStage)
MessageBox(NULL, "\tVictim process attach succesfully!", szMsgCapt, MB_OK);
}
// --------------------------------------------
// Main debugger cycle
// --------------------------------------------
DEBUG_EVENT DebugEv; // debugging event information
DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation
HMODULE hDLL; // temp handle used for target function offset calculation
for(;;)
{
// Wait for a debugging event to occur. The second parameter indicates
// that the function does not return until a debugging event occurs.
// We are waiting for infinite time, then wait for each Debug Event.
WaitForDebugEvent(&DebugEv, INFINITE);
// If we're into the first event save the process thread handle
if (!bFirstEvent)
{
hVictimThreadHandle = DebugEv.u.CreateProcessInfo.hThread;
bFirstEvent = true;
}
// Process the debugging event code.
switch (DebugEv.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
// Process the exception code. When handling
// exceptions, remember to set the continuation
// status parameter (dwContinueStatus). This value
// is used by the ContinueDebugEvent function.
// Increment exception counter (not used)
iExceptionCounter++;
// Show the current exception number
if (bShowExcpNumber && bDebugStage)
{
sprintf(szMsgText,"Exception number %d",iExceptionCounter);
MessageBox(NULL, szMsgText, szMsgCapt, MB_OK);
}
// Check if this is the right exception by reading the context
// structure for the victim process. Before to do it set the ContextFlags to READ_ALL
victimContext.ContextFlags = 0x1003F;
// Exception handler
switch(DebugEv.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
// First chance: Pass this on to the system.
// Last chance: Display an appropriate error.
// MessageBox(NULL, "EXCEPTION_ACCESS_VIOLATION", "Debugger advise", MB_OK);
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
break;
case EXCEPTION_BREAKPOINT:
// First chance: Display the current
// instruction and register values.
// This exception will be called during the system breakpoint
// Check about system breakpoint, if yes we have to place a breakpoint
// into the MSVBVM60.DLL on the "szVictimDLLfunc" exported function
if (!bSystemBreakpoint)
{
// Enumerate all module
iVictimDLLBaseAddress = EnumAllProcesModule(aVictimProcessId, szVictimDLLname, bDebugStage);
if (!iVictimDLLBaseAddress)
{
sprintf(szMsgText,"Can't read proces module\n");
MessageBox(NULL, szMsgText, szMsgCapt, MB_OK);
return;
}
// LoadLibrary in order to know the function address, the right address
// into the victim memory space can be found by using the right offset from
// the base address and the API address when the same DLL is loaded into the
// loader address space (copy is the same then offset is the same).
// When you've the offset to find the real address into the victim space simply
// add this offset to the base address of the target DLL mappend into the victim space
// base address came from EnumAllProcesModule function.
hDLL = LoadLibrary(szVictimDLLname); // Base address into the loader space
FARPROC addrIDPBreakpoint; // Used to store the real address (victim space)
DWORD apiOffset; // Used to store the function offset into the victim DLL
addrIDPBreakpoint = GetProcAddress(hDLL, szVictimDLLfunc); // Load the absolute address for the victim function into the loader space
apiOffset = (DWORD)addrIDPBreakpoint-(DWORD)hDLL; // Calculate the function offset (same for loader and victim space)
addrIDPBreakpoint = (FARPROC)((DWORD)iVictimDLLBaseAddress + (DWORD)apiOffset); // Calculate the real address into the victim space
if (addrIDPBreakpoint != NULL)
{
if (bDebugStage)
{
sprintf(szMsgText,"%s Address %X", szVictimDLLfunc, (DWORD)addrIDPBreakpoint);
MessageBox(NULL, szMsgText, szMsgCapt, MB_OK);
}
}
else
{
sprintf(szMsgText,"Can't place breakpoint");
MessageBox(NULL, szMsgText, szMsgCapt, MB_OK);
if (hDLL != NULL)
FreeLibrary(hDLL);
CloseHandle(hTmpProcess);
return;
}
// Now we can open the process to place breakpoint (iPatchData[0] = 0xCC -> INT3
hTmpProcess = OpenProcess( PROCESS_ALL_ACCESS | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, aVictimProcessId);
if (!WriteProcessMemory(hTmpProcess, (LPVOID)(addrIDPBreakpoint), &iPatchData[0], 1, NULL))
{
ErrorExit("WriteProcessMemory ERROR: ");
MessageBox(NULL, "I can't write process memory :-(", szMsgCapt, MB_OK);
if (hDLL != NULL)
FreeLibrary(hDLL);
CloseHandle(hTmpProcess);
return;
}
bSystemBreakpoint = true;
// Free the library
if (hDLL != NULL)
FreeLibrary(hDLL);
// Hide debugger from ASProtect IsDebuggerPresent API calling
HideDebugger(hVictimThreadHandle,hTmpProcess);
// Now we can close the process HANDLE
CloseHandle(hTmpProcess);
}
else
{
// We are in our INT3 breakpoint
if (bDebugStage)
{
sprintf(szMsgText,"%s BREAKPOINT", szVictimDLLfunc);
MessageBox(NULL, szMsgText, szMsgCapt, MB_OK);
}
// Now I've to read the stack in order to fish the right serial
// then first I've to keep the process CONTEXT
victimContext.ContextFlags = 0x1003F;
if (!GetThreadContext( hVictimThreadHandle, &victimContext))
{
ErrorExit("GetThreadContext ERROR: ");
return;
}
if (bDebugStage)
{
printf("Stack pointer ESP = %X\n",victimContext.Esp);
printf("Stack pointer EIP = %X\n",victimContext.Eip);
}
// Read the stack into the ESP+8 address, in this address we have
// the fake serial entered by the user in UNICODE format
hTmpProcess = OpenProcess( PROCESS_ALL_ACCESS | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, aVictimProcessId);
// Read the pointer to the fake serial
DWORD FakeSerialPtr;
DWORD FakeVariantPtr, RightVariantPtr;
//skip a DWORD
ReadProcessMemory(hTmpProcess, (LPVOID)((victimContext.Esp) + 4), &FakeVariantPtr, sizeof(DWORD), NULL);
ReadProcessMemory(hTmpProcess, (LPVOID)((victimContext.Esp) + 4*2), &RightVariantPtr, sizeof(DWORD), NULL);
ReadProcessMemory(hTmpProcess, (LPVOID)((FakeVariantPtr) + 8), &FakeSerialPtr, sizeof(DWORD), NULL);
if (bDebugStage) {
printf("Fake serial pointer: %X\n",FakeSerialPtr);
}
// Read the pointer value to the right serial which is in ESP+12
DWORD RightSerialPtr;
ReadProcessMemory(hTmpProcess, (LPVOID)(RightVariantPtr + 8), &RightSerialPtr, sizeof(DWORD), NULL);
if (bDebugStage) {
printf("Right serial pointer: %X\n",RightSerialPtr);
}
// Now we have to collect the serial code byte by using ReadProcessMemory, remember
// this is in UNICODE format then we have to check about the string end, this is easily
// achieved by checking the current data byte, if this is 0 we have reached the string end
int iAddrPtr, iBufferPtr;
iAddrPtr=0;
iBufferPtr=0;
do
{
ReadProcessMemory(hTmpProcess, (LPVOID)(FakeSerialPtr + (DWORD)iAddrPtr), &iOridataReadOne, 1, NULL);
iAddrPtr=iAddrPtr+2;
szFakeSerial[iBufferPtr++]=iOridataReadOne;
}
while (iOridataReadOne != 0);
szFakeSerial[iBufferPtr]='\0'; // Place the string terminator
// Now we have to read the right serial number (same things as fake serial)
iAddrPtr=0;
iBufferPtr=0;
do
{
ReadProcessMemory(hTmpProcess, (LPVOID)(RightSerialPtr + (DWORD)iAddrPtr), &iOridataReadOne, 1, NULL);
iAddrPtr=iAddrPtr+2;
szRightSerial[iBufferPtr++]=iOridataReadOne;
}
while (iOridataReadOne != 0);
szRightSerial[iBufferPtr]='\0'; // Place the string terminator
// Now we have to show our serial fishing to the user :)
sprintf(szMsgText,"\tFake serial: %s\n\tRight serial: %s\n\tCopy and paste to register appz!",szFakeSerial,szRightSerial);
printf(szMsgText);
MessageBox(NULL, szMsgText, szMsgCapt, MB_OK);
// Before finish we have to restore the original value (0x55) into the
// MSVBVM60.DLL and restore the EIP to the breakpoint address
hDLL = LoadLibrary(szVictimDLLname);
FARPROC addrIDPBreakpoint;
DWORD apiOffset;
addrIDPBreakpoint = GetProcAddress(hDLL, szVictimDLLfunc);
apiOffset = (DWORD)addrIDPBreakpoint-(DWORD)hDLL;
addrIDPBreakpoint = (FARPROC)((DWORD)iVictimDLLBaseAddress + (DWORD)apiOffset);
if (!WriteProcessMemory(hTmpProcess, (LPVOID)addrIDPBreakpoint, &iOridata[0], 1, NULL))
{
ErrorExit("WriteProcessMemory ERROR: ");
MessageBox(NULL, "I can't write process memory :-(", szMsgCapt, MB_OK);
return;
}
if (hDLL != NULL)
FreeLibrary(hDLL);
if (hPsapi != NULL)
FreeLibrary(hPsapi);
// Restore the EIP
victimContext.Eip =(victimContext.Eip) - 1;
if (!SetThreadContext( hVictimThreadHandle, &victimContext))
{
ErrorExit("GetThreadContext ERROR: ");
}
// Close the temp handle for the process
CloseHandle(hTmpProcess);
// Run the victim process
ContinueDebugEvent(DebugEv.dwProcessId,DebugEv.dwThreadId, DBG_CONTINUE);
// Stop debugger action and let program run freely
BOOL bDbgStopFlag = DebugActiveProcessStop(aVictimProcessId);
// Exit from debugger
return;
}
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
// First chance: Pass this on to the system.
// Last chance: Display an appropriate error.
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
break;
case EXCEPTION_SINGLE_STEP:
// First chance: Update the display of the
// current instruction and register values.
if (bDebugStage)
printf("EXCEPTION_SINGLE_STEP\n");
break;
case DBG_CONTROL_C:
// First chance: Pass this on to the system.
// Last chance: Display an appropriate error
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
break;
default:
// Handle other exceptions.
break;
}
case CREATE_THREAD_DEBUG_EVENT:
// As needed, examine or change the thread's registers
// with the GetThreadContext and SetThreadContext functions;
// and suspend and resume thread execution with the
// SuspendThread and ResumeThread functions.
if (bDebugStage)
printf("CREATE_THREAD_DEBUG_EVENT %X\n",DebugEv.u.CreateThread.hThread);
break;
case CREATE_PROCESS_DEBUG_EVENT:
// As needed, examine or change the registers of the
// process's initial thread with the GetThreadContext and
// SetThreadContext functions; read from and write to the
// process's virtual memory with the ReadProcessMemory and
// WriteProcessMemory functions; and suspend and resume
// thread execution with the SuspendThread and ResumeThread
// functions. Be sure to close the handle to the process image
// file with CloseHandle.
// Hide debugger
dwContinueStatus = DBG_CONTINUE;
break;
case EXIT_THREAD_DEBUG_EVENT:
// Display the thread's exit code.
break;
case EXIT_PROCESS_DEBUG_EVENT:
// Target RegBackup process is closed from user, then we have
//to stop the debugger work and exit from loader
if (bDebugStage)
{
printf("\nHi mate, I hope to see you soon\n");
sprintf(szMsgText,"Hi mate, I hope to see you soon.");
MessageBox(NULL, szMsgText, szMsgCapt, MB_OK);
}
// Exit from loader
ContinueDebugEvent(DebugEv.dwProcessId,DebugEv.dwThreadId, DBG_CONTINUE);
return;
break;
case LOAD_DLL_DEBUG_EVENT:
// Read the debugging information included in the newly
// loaded DLL. Be sure to close the handle to the loaded DLL
// with CloseHandle.
if (bDebugStage)
printf("DLL load address: %X\n",DebugEv.u.LoadDll.lpBaseOfDll,DebugEv.u.LoadDll.lpBaseOfDll);
break;
case UNLOAD_DLL_DEBUG_EVENT:
// Display a message that the DLL has been unloaded.
break;
case OUTPUT_DEBUG_STRING_EVENT:
// Display the output debugging string.
break;
}
// Resume executing the thread that reported the debugging event.
ContinueDebugEvent(DebugEv.dwProcessId,DebugEv.dwThreadId, dwContinueStatus);
}
// ------------------------
// Closing
// ------------------------
if (hPsapi != NULL)
FreeLibrary(hPsapi);
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -