📄 loaderactions.cpp
字号:
// LoaderActions.cpp : Defines the entry point for the console application.
//
#include "LoaderActions.h"
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
Loader::Loader()
{
//TODO: insert specific actions if you require additional initialization
SetStartingMsg("Loader working...wait a little\nCreditz 2 Shub-Nigurrath & ThunderPwr [at] ARTEam");
}
Loader::~Loader()
{
//TODO: insert specific actions if you require additional de-initialization
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//Receives
//- the Stack of Patch elements that must be properly filled
//- the victim file name, containing a valid path to the pathced file
BOOL Loader::InitializePatchStack(growing_arraystack<Patch> &stkPatches)
{
//////////////////////////////////////////////////////////////////////////
//This is the filling of the patches stack.
//you can use one of the constructors available.
// The first only requires the patch address and the new byte
// so no controls will be performed later, the loader will only do a simply
// write to that memory section, regardless of the read value.
// The second way, used here is to also add the original bytes, doing so
// the loader will also check if the byte read at the memory location specified
// is equal to the original byte you expected to be there.
// if not the patch is not applied.
// The third one allows to specify a callback which is called when trying to perform
// the patch.
//Note that the patches are all applied subsequently after the gate condition is met
//(see GateProcedure())
//NB 0x00 must explicitly converted to BYTE because otherwise the complier confuses
//it with a NULL pointer and doesn't know which constructor of class Patch to use.
//TODO: insert specific patches for the target
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//Simply used to specify the victim's filename, received the storing variable.
BOOL Loader::SetVictimDetails(TextString &victimFileName)
{
//TODO: customize this function, according to the target needs
#ifndef _DEBUG
victimFileName=TextString(".\\_Target.exe");
#else
victimFileName=TextString("c:\\complete_path_to_installation_folder\\_Target.exe");
#endif
//Set this parameter to true when you want the loader to check the CRC of the file!
//Otherwise comment the line
SetVictimCRC(0xABCDEF);
SetCreateProcessFlags(DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
BOOL Loader::ActionsBeforeGateProcedure()
{
//TODO: insert specific actions
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//THE FUNCTION GATEPROCEDURE MUST ALWAYS BE DEFINED WITH THIS PROTOTYPE.
//RETURNED VALUE IS TRUE WHEN THE MATCHING CONDITION REQUIRED TO START
//THE PATCH IS MET.
//OFTEN THIS FUNCTION SIMPLY CHECKS FOR A SPECIFIED DWORD VALUE IN A SPECIFIED
//MEMORY LOCATION, AFTER WHICH THE CHECKS HAVE ALL BEEN SUCCESFULLY DONE.
BOOL Loader::GateProcedure()
{
//TODO: customize the test when you receive the or the EXCEPTION_DEBUG_EVENT event or any other exception you want to handle
//(the example is for AsProtect 1.2x versions)
//To exit write a "throw TRUE;", the final catch will handle the rest.
BOOL bRet=FALSE;
DEBUG_EVENT DebugEv; // debugging event information
DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation
// Define the CONTEXT structure used to load the victim process context
// when debugged process break due to exception event
CONTEXT victimContext;
int iExceptionCounter = 0;
BYTE OridataRead[2];
memset(OridataRead,0,sizeof(BYTE)*2);
try {
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);
// 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++;
#ifdef _DEBUG
// Show the current exception number
// char str[256];
// sprintf(str,"Exception number %d", iExceptionCounter);
// ::MessageBox(NULL, str, DEFAULT_MSG_CAPTION, MB_OK);
#endif
// 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;
// Fill the process CONTEXT with the process information
GetThreadContext(GetPI()->hThread , &victimContext);
// Now I've to scan the process memory in order to see if I can
// found the PUSH 0C instruction (19 byte after exception)
ReadProcessMemory(GetPI()->hProcess, (LPVOID)((victimContext.Eip) + 19), &OridataRead, 2, NULL);
//6A 0C PUSH 0C
if ((OridataRead[0] == 0x6A) && (OridataRead[1] == 0x0C))
{
// Key location found, now we can apply the patch
#ifdef _DEBUG
char str[256];
sprintf(str,"Found PUSH 0C location");
MessageBox(NULL, str, DEFAULT_MSG_CAPTION, MB_OK);
#endif
throw TRUE; //This is the way to exit from the GateCondition
}
// 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.
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
}
break;
case EXCEPTION_BREAKPOINT: {
// First chance: Display the current
// instruction and register values.
}
break;
case EXCEPTION_DATATYPE_MISALIGNMENT: {
// First chance: Pass this on to the system.
// Last chance: Display an appropriate error.
}
break;
case EXCEPTION_SINGLE_STEP: {
// First chance: Update the display of the
// current instruction and register values.
}
break;
case DBG_CONTROL_C: {
// First chance: Pass this on to the system.
// Last chance: Display an appropriate error.
}
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.
}
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.
dwContinueStatus = DBG_CONTINUE;
}
break;
case EXIT_THREAD_DEBUG_EVENT: {
// Display the thread's exit code.
}
break;
case EXIT_PROCESS_DEBUG_EVENT: {
// Target Process is closed from user, then we have
//to stop the debugger work and exit from loader
// Exit form loader
ContinueDebugEvent(DebugEv.dwProcessId,DebugEv.dwThreadId, DBG_CONTINUE);
throw FALSE;
}
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.
}
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);
} //end for(;;)
} //end try
catch(BOOL bRet) {
return bRet;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
BOOL Loader::ActionsAfterGateProcedure()
{
//Stop debugger action and let program run freely
DWORD dwProcessId = GetProcessId(GetPI()->hProcess);
BOOL bDbgStopFlag = DebugActiveProcessStop(dwProcessId);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//This function is called just before the call to CreateProcess. Could be left empty.
BOOL Loader::ActionsBeforeCreateProc()
{
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//This function is called just before the process has been created but it is still in waiting mode
BOOL Loader::ActionsAfterCreateProc()
{
HideDebugger(GetPI()->hThread, GetPI()->hProcess);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//This function is called just before closing the loader, after all the actions have been performed.
BOOL Loader::ActionsBeforeClosingLoader()
{
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -