- // this
patcher is for Avisplitter 3.01
#include "stdafx.h"
#include <windows.h>
bool SetBreakpoint(PROCESS_INFORMATION &pi,
int address, unsigned char expectedByte)
{
unsigned char charBuffer;
if (!ReadProcessMemory(pi.hProcess, (void*)address,
&charBuffer, 1, NULL))
{
return false;
}
if (charBuffer!=expectedByte)
{
return false;
}
charBuffer = 0xCC;
if (!WriteProcessMemory(pi.hProcess, (void*)address,
&charBuffer, 1, NULL))
{
return false;
}
return true;
}
bool AdjustInstructionPointer(HANDLE hThread, int delta)
{
CONTEXT context;
context.ContextFlags = 0x1003F; // CONTEXT_ALL
if (!GetThreadContext(hThread,&context))
{
return false;
}
context.Eip+=delta;
if (!SetThreadContext(hThread,&context))
{
return false;
}
return true;
}
bool ClearBreakpoint(PROCESS_INFORMATION &pi,
int address, unsigned char originalByte)
{
unsigned char charBuffer;
if (!ReadProcessMemory(pi.hProcess, (void*)address,
&charBuffer, 1, NULL))
{
return false;
}
if (charBuffer!=0xCC)
{
return false;
}
charBuffer = originalByte;
if (!WriteProcessMemory(pi.hProcess, (void*)address,
&charBuffer, 1, NULL))
{
return false;
}
return AdjustInstructionPointer(pi.hThread, -1);
}
bool WaitForEventAtAddress(DEBUG_EVENT &de,int addressExpected,
DWORD &dwContinueStatus)
{
int address;
bool boolDebugging = true;
while (boolDebugging)
{
dwContinueStatus = DBG_CONTINUE;
if
(!WaitForDebugEvent(&de,INFINITE))
{
return false;
}
if (de.dwDebugEventCode ==
EXCEPTION_DEBUG_EVENT)
{
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
address = (DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress;
if
((de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
||
(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP))
{
dwContinueStatus = DBG_CONTINUE;
}
}
if (address ==
addressExpected)
{
boolDebugging = false;
}
else
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus);
}
return true;
}
int WaitForExitOrEventAtAddress(DEBUG_EVENT &de,int
addressExpected, DWORD &dwContinueStatus)
{
/*
returns
0 on error
1 if execution reaches
addressExpected
2 if
EXIT_PROCESS_DEBUG_EVENT is signaled
*/
int address;
bool boolDebugging = true;
while (boolDebugging)
{
dwContinueStatus = DBG_CONTINUE;
if
(!WaitForDebugEvent(&de,INFINITE))
{
return 0;
}
if (de.dwDebugEventCode ==
EXCEPTION_DEBUG_EVENT)
{
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
address = (DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress;
if
((de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
||
(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP))
{
dwContinueStatus = DBG_CONTINUE;
}
}
if (address ==
addressExpected)
{
return 1;
}
else if (de.dwDebugEventCode ==
EXIT_PROCESS_DEBUG_EVENT)
return 2;
else
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus);
}
return 0;
}
bool SoftwareBreakpointAt(PROCESS_INFORMATION &pi, int baseAddress,
unsigned char
byteExpected, DEBUG_EVENT &de,
DWORD
&dwContinueStatus)
{
if (!SetBreakpoint(pi, baseAddress, byteExpected))
return false;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
if
(!WaitForEventAtAddress(de,baseAddress,dwContinueStatus))
return false;
if (!ClearBreakpoint(pi,baseAddress,byteExpected))
return false;
return true;
}
bool WaitForSingleStep(DEBUG_EVENT &de, DWORD &dwContinueStatus)
{
int address;
bool boolDebugging = true;
while (boolDebugging)
{
dwContinueStatus = DBG_CONTINUE;
if
(!WaitForDebugEvent(&de,INFINITE))
{
return false;
}
if (de.dwDebugEventCode ==
EXCEPTION_DEBUG_EVENT)
{
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
address = (DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress;
if
((de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
||
(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP))
{
dwContinueStatus = DBG_CONTINUE;
}
if
(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP)
{
return true;
}
}
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus);
}
return true;
}
bool WaitForExitProcess(DEBUG_EVENT &de, DWORD
&dwContinueStatus)
{
int address;
bool boolDebugging = true;
while (boolDebugging)
{
dwContinueStatus = DBG_CONTINUE;
if
(!WaitForDebugEvent(&de,INFINITE))
{
return false;
}
if (de.dwDebugEventCode ==
EXCEPTION_DEBUG_EVENT)
{
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
address = (DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress;
if
((de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
||
(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP))
{
dwContinueStatus = DBG_CONTINUE;
}
}
else if (de.dwDebugEventCode ==
EXIT_PROCESS_DEBUG_EVENT)
return true;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus);
}
return true;
}
bool SetEaxValue(PROCESS_INFORMATION &pi, DWORD newValue)
{
CONTEXT context;
context.ContextFlags = 0x1003F; //CONTEXT_ALL;
if (!GetThreadContext(pi.hThread,&context))
{
return false;
}
context.Eax = newValue;
if (!SetThreadContext(pi.hThread,&context))
{
return false;
}
return true;
}
bool SetEipValue(PROCESS_INFORMATION &pi, DWORD newValue)
{
CONTEXT context;
context.ContextFlags = 0x1003F; //CONTEXT_ALL;
if (!GetThreadContext(pi.hThread,&context))
{
return false;
}
context.Eip = newValue;
if (!SetThreadContext(pi.hThread,&context))
{
return false;
}
return true;
}
bool SetZFlag(PROCESS_INFORMATION &pi)
{
CONTEXT context;
context.ContextFlags = 0x1003F; //CONTEXT_ALL;
if (!GetThreadContext(pi.hThread,&context))
{
return false;
}
context.EFlags = context.EFlags | 0x40; // 1000000
if (!SetThreadContext(pi.hThread,&context))
{
return false;
}
return true;
}
bool ClearZFlag(PROCESS_INFORMATION &pi)
{
CONTEXT context;
context.ContextFlags = 0x1003F; //CONTEXT_ALL;
if (!GetThreadContext(pi.hThread,&context))
{
return false;
}
context.EFlags = context.EFlags & (~(0x40)); //
1000000
if (!SetThreadContext(pi.hThread,&context))
{
return false;
}
return true;
}
bool SetTrapFlag(PROCESS_INFORMATION &pi)
{
CONTEXT context;
context.ContextFlags = 0x1003F; //CONTEXT_ALL;
if (!GetThreadContext(pi.hThread,&context))
{
return false;
}
context.EFlags = context.EFlags | 0x100; // 100000000
if (!SetThreadContext(pi.hThread,&context))
{
return false;
}
return true;
}
bool ClearTrapFlag(PROCESS_INFORMATION &pi)
{
CONTEXT context;
context.ContextFlags = 0x1003F; //CONTEXT_ALL;
if (!GetThreadContext(pi.hThread,&context))
{
return false;
}
context.EFlags = context.EFlags & (~(0x100)); //
100000000
if (!SetThreadContext(pi.hThread,&context))
{
return false;
}
return true;
}
int main(int argc, char* argv[])
{
//launch target
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcess( "VideoSplitter.exe",
NULL,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS |
DEBUG_ONLY_THIS_PROCESS,
NULL,
NULL,
&si,
&pi )
)
{
return -1;
}
bool boolDebugging = true;
DEBUG_EVENT de;
DWORD dwContinueStatus;
DWORD address = 0;
int baseAddress;
// 1)
if
(!WaitForEventAtAddress(de,0x004e7ae7,dwContinueStatus))
return -1;
// 2)
-
baseAddress = 0x004E86DB;
if (!SoftwareBreakpointAt(pi,baseAddress, 0xFF, de,
dwContinueStatus))
return -1;
// 3)
-
baseAddress = 0x004C80BD;
if (!SetBreakpoint(pi, baseAddress, 0x85))
return -1;
baseAddress = 0x004c84ad;
if (!SetBreakpoint(pi, baseAddress, 0x85))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
// 4)
if (!WaitForEventAtAddress(de,0x004C80BD,dwContinueStatus))
return -1;
baseAddress = 0x004C80BD;
if (!ClearBreakpoint(pi,baseAddress,0x85))
return -1;
if (!SetEaxValue(pi, 1))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
-
// 5)
if
(!WaitForEventAtAddress(de,0x004c84ad,dwContinueStatus))
return -1;
baseAddress = 0x004c84ad;
if (!ClearBreakpoint(pi,baseAddress,0x85))
return -1;
if (!SetEaxValue(pi, 1))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
// 6)
if (!WaitForEventAtAddress(de,0x00A58006,dwContinueStatus))
return -1;
-
// 7)
baseAddress = 0x00A6D8BC;
if (!SoftwareBreakpointAt(pi,baseAddress, 0x8B, de,
dwContinueStatus))
return -1;
-
// 8)
baseAddress = 0x00A6DAA5;
if (!SoftwareBreakpointAt(pi,baseAddress, 0x74, de,
dwContinueStatus))
return -1;
-
// 9)
if (!SetZFlag(pi))
return -1;
-
// 10)
if (!SetTrapFlag(pi))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
-
// 11)
if(!WaitForSingleStep(de,dwContinueStatus))
return -1;
-
// 12)
if
(!SoftwareBreakpointAt(pi,baseAddress,0x74,de,dwContinueStatus))
return -1;
-
// 13)
if (!SetZFlag(pi))
return -1;
-
// 14)
if (!SetTrapFlag(pi))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
-
// 15)
if(!WaitForSingleStep(de,dwContinueStatus))
return -1;
// 16)
baseAddress = 0x00a78c8e;
if (!SoftwareBreakpointAt(pi,baseAddress, 0xFF, de,
dwContinueStatus))
return -1;
-
// 17)
baseAddress = 0x0040F210;
if (!SoftwareBreakpointAt(pi,baseAddress, 0x83, de,
dwContinueStatus))
return -1;
-
// 18)
if (!SetEaxValue(pi, 0x0A))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
bool programRunning = true;
while (programRunning)
{
-
// 19)
int retValue =
WaitForExitOrEventAtAddress(de,0x00414274,dwContinueStatus);
switch(retValue)
{
case 0:
return -1;
break;
case 1:
break;
case 2:
-
// 20)
return 0;
break;
}
-
// 20)
if (!SetEipValue(pi, 0x00414279))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
-
// 21)
if
(!WaitForEventAtAddress(de,0x00414298,dwContinueStatus))
return -1;
-
// 22)
if (!SetEipValue(pi, 0x0041429A))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
-
// 23)
if
(!WaitForEventAtAddress(de,0x004142e8,dwContinueStatus))
return -1;
-
// 24)
if (!SetEipValue(pi, 0x004142ed))
return -1;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId,
dwContinueStatus);
}
return 0;
}
|