📄 debugger.pas
字号:
assemble('PUSHAD',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
//loadlibrary(cehook);
assemble('PUSH '+IntToHex(dword(injectedlocation),8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('CALL '+IntToHex(dword(LoadLibraryPtr),8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
//getprocaddress
assemble('PUSH '+IntToHex(ihwciloc,8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('PUSH EAX',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('CALL '+IntToHex(dword(GetProcAddressPtr),8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('CALL EAX',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
assemble('POPAD',position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
//jump to original start address
assemble('JMP '+IntToHex(AddressOfEntryPoint,8),position,outp);
copymemory(@inject[position2],outp,length(outp));
inc(position,length(outp));
inc(position2,length(outp));
//call the routine
writeprocessmemory(processhandle,injectedlocation,@inject[0],position2,x);
result:=startaddress;
//showmessage('Injected code at: '+IntToHex(dword(injectedlocation),8)+' startaddress='+IntToHex(startaddress,8));
finally
FreeLibrary(h);
end;
{$endif}
end;
procedure TDebugger.Execute;
var startupinfo:_STARTUPINFOA;
int3: byte;
devent: _Debug_EVENT;
processinfo:_Process_information; //make an array of this
i,j: integer;
original: dword;
tobefrozen: integer; //-1 is none
notinlist: boolean;
tid,thnd: dword;
//----
temp: dword;
desc,opcode: string;
seperator: integer;
fb: integer;
nb: integer;
address: string;
offset:dword;
errorlog: textfile;
times: integer;
debugpatch: integer;
previousexception: dword;
mbi : _MEMORY_BASIC_INFORMATION;
hthr: thandle;
asciistring: pansichar;
unicodestring: pwidechar;
bytesread: dword;
err:string;
found: boolean;
a,b,c: dword;
ab: byte;
SelectorEntry:_LDT_ENTRY;
oldcontext: _CONTEXT;
exefile: File;
dosheader: ^IMAGE_DOS_HEADER;
Optionalheader: ^IMAGE_OPTIONAL_HEADER;
ExeHeader: array [0..4095] of byte;
AddressOfEntryPoint:dword;
dotnet: boolean;
firstbreak: boolean;
creationhandleD: boolean;
begin
AddressOfEntryPoint:=0;
setlength(processes,0);
creationhandleD:=false;
zeromemory(@drregs,sizeof(drregs));
drregs.ContextFlags:=CONTEXT_DEBUG_REGISTERS;
previousexception:=0;
times:=0;
debugpatch:=0;
FreeOnTerminate:=true;
int3:=$cc;
breakpointset:=false;
attached:=false;
readonlyset:=false;
processhandle:=0;
tobefrozen:=-1;
//GetStartUpInfo(STARTUPINFO);
FillMemory(@STARTUPINFO,sizeof(STARTUPINFO),0);
STARTUPINFO.cb :=sizeof(STARTUPINFO);
try
if createaprocess then
begin
//create a process
filemode:=0;
assignfile(exefile,filename);
try
reset(exefile,1);
except
attaching:=false;
err:='The file can''t be opened!';
messagebox(0,pchar(err),'Create failure',mb_ok);
exit;
end;
try
temp:=0;
blockread(exefile,exeheader[0],4096,temp);
if temp>0 then
begin
dosheader:=@exeheader[0];
optionalheader:=pointer(dword(dosheader)+dosheader._lfanew+24);
AddressOfEntryPoint:=optionalheader.ImageBase+optionalheader.AddressOfEntryPoint;
end;
finally
closefile(exefile);
end;
if not Createprocess(nil,pchar(filename+' '+parameters),nil,nil,false,(CREATE_SUSPENDED or DEBUG_PROCESS or NORMAL_PRIORITY_CLASS),nil,nil,Startupinfo,processinfo) then
begin
attaching:=false;
err:='Cheat Engine failed to create the process. (Error='+pchar(IntToStr(GetLastError))+')';
messagebox(0,pchar(err),'Create failure',mb_ok);
{$ifndef net}
postmessage(mainform.Handle,WM_USER+1,0,0);
{$endif}
exit;
end;
readprocessmemory(processinfo.hProcess,pointer(addressofentrypoint),@originalbyte,1,temp);
{ dotneT:=false;
firstbreak:=true;
if originalbyte=$ff then
begin
readprocessmemory(processinfo.hProcess,pointer(addressofentrypoint+1),@ab,1,temp);
if ab=$25 then dotnet:=true;
end;
if not dotnet then writeprocessmemory(processinfo.hProcess,pointeR(AddressOfEntryPoint),@int3,1,temp);
}
// messagebox(0,pchar(IntToHex(Context.Eax,8)),pchar(IntTOHex(Context.Eax,8)),MB_OK );
resumethread(processinfo.hThread);
end
else
begin
// BOOL DebugActiveProcess(DWORD dwProcessId)=
{
if(DbgUiConnectToDbg())
{
HANDLE hProcess = ProcessIdToHandle(dwProcessId);
if(hProcess)
{
DbgUiDebugActiveProcess(hProcess);
NtClose(hProcess);
}
// }
// return FALSE;
// }
//attach to a running process
//rewrite nt
{$ifdef netserver}
RestoreNTOpenProcess;
{$else}
if formsettings.cbKernelOpenProcess.checked then
RestoreNTOpenProcess;
{$endif}
if not DebugActiveProcess(Openprocessid) then
begin
attaching:=false;
{$ifndef net}
err:='Cheat Engine failed to attach to the process. (Error='+IntToStr(GetLastError)+')';
messagebox(0,pchar(err),'Attach failure',mb_ok);
postmessage(mainform.Handle,WM_USER+1,0,0); //set debuggerthread to nil
{$endif}
exit;
end;
end;
DebugSetProcessKillOnExit(true); //WHY DOESN'T IT WORK LIKE I WANT TO?
running:=true;
while not terminated and debugging do
begin
if WaitForDebugEvent(devent,4000) then //4 seconds wont cause a hog I hope
begin
try
crdebugging.Acquire;
//working on a debug thing
currentprocess:=-1;
for i:=0 to length(newprocesses)-1 do
if newprocesses[i].processid=devent.dwProcessId then
begin
currentprocess:=i;
break;
end;
if length(newprocesses)>0 then
processhandle:=newprocesses[length(newprocesses)-1].processhandle;
case devent.dwDebugEventCode of
EXCEPTION_DEBUG_EVENT:
begin
if newprocesses[currentprocess].firstbreak then
begin
if newprocesses[currentprocess].dotnet then
begin
//jump near (I assume the next byte is a $25
if readprocessmemory(newprocesses[currentprocess].processhandle,pointer(addressofentrypoint+2),@a,4,temp) then
begin
readprocessmemory(newprocesses[currentprocess].processhandle,pointer(a),@b,4,temp);
newprocesses[currentprocess].EntryPoint:=b;
readprocessmemory(newprocesses[currentprocess].processhandle,pointer(b),@newprocesses[currentprocess].OriginalEntryByte,1,temp);
writeprocessmemory(newprocesses[currentprocess].processhandle,pointeR(b),@int3,1,temp);
end;
end;
if hidedebugger then RemoveDebuggerDetection(newprocesses[currentprocess].processhandle);
newprocesses[currentprocess].firstbreak:=false;
end;
// if devent.Excdeeption.dwFirstChance=0 then MessageBox(0,'seconde time','second time',MB_OK);
//this is called after the threadlist has been initialised
for i:=0 to length(threadlist)-1 do
if threadlist[i,0]=devent.dwThreadId then
begin
context.ContextFlags:=CONTEXT_FULL;
getthreadcontext(threadlist[i,1],context);
pausedthreadhandle:=threadlist[i,1];
break;
end;
if createaprocess and (context.eip=newprocesses[currentprocess].EntryPoint+1) then
begin
creationHandled:=true;
writeprocessmemory(newprocesses[currentprocess].processhandle,pointeR(newprocesses[currentprocess].EntryPoint),@newprocesses[currentprocess].OriginalEntryByte ,1,temp);
context.ContextFlags:=context_full;
outputdebugstring('Injecting dll');
context.Eip:=injectcode(newprocesses[currentprocess].EntryPoint,newprocesses[currentprocess].processhandle)+1;
SetThreadcontext(pausedthreadhandle,context);
if createdusingprocesswindow and (currentprocess=0) then
begin
//set a breakpoint at the AddressOfEntryPoint
if not attached then
begin
attached:=true;
attaching:=false;
synchronize(ProcessCreated);
end;
debugging:=ContinueDebugEvent(devent.dwProcessId,devent.dwThreadId,DBG_CONTINUE);
continue;
end;
end;
if attached and {hidedebugger and} (not userisdebugging) then
if readprocessmemory(newprocesses[currentprocess].processhandle,pointeR(context.eip-1),@ab,1,a) then
begin
if ab=int3 then
begin
if (not createaprocess) or (creationHandled) then
begin
if (context.Eip-1)<>DbgBreakPointLocation then
begin
if handlebreakpoints then
debugging:=ContinueDebugEvent(devent.dwProcessId,devent.dwThreadId,DBG_CONTINUE)
else
debugging:=ContinueDebugEvent(devent.dwProcessId,devent.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
outputdebugstring('err1');
continue;
end;
end;
end;
end;
if not attached then
begin
attached:=true;
attaching:=false;
synchronize(ProcessCreated);
end;
i:=0;
//find out what exception it is
if devent.Exception.ExceptionRecord.ExceptionCode=EXCEPTION_BREAKPOINT then
begin
if userisdebugging then
begin
//check if this is a exception breakpoint that was made by cheat engine
addressfound:=dword(devent.Exception.ExceptionRecord.ExceptionAddress);
found:=(int3CEBreakpoint.address=addressfound);
for i:=0 to length(int3userbreakpoints)-1 do
if (int3userbreakpoints[i].address=addressfound) then found:=true;
if found or createdusingprocesswindow then
begin
//we have a confirmation....
//set the byte back
if not createdusingprocesswindow then
removebreakpoint;
createdusingprocesswindow:=false;
if int3CEBreakpoint.address=addressfound then
begin
int3CEBreakpoint.address:=0;
int3CEBreakpoint.originalbyte:=0;
end;
//set eip back
dec(context.Eip);
notinlist:=true;
for i:=0 to length(registermodificationBPs)-1 do
if registermodificationBPs[i].address=context.eip then
begin
notinlist:=false;
//modify the context of this thread according to the data in registermodificationBPs[i]
if registermodificationBPs[i].change_eax then context.Eax:=registermodificationBPs[i].new_eax;
if registermodificationBPs[i].change_ebx then context.Ebx:=registermodificationBPs[i].new_ebx;
if registermodificationBPs[i].change_ecx then context.Ecx:=registermodificationBPs[i].new_ecx;
if registermodificationBPs[i].change_edx then context.Edx:=registermodificationBPs[i].new_edx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -