📄 debugger.pas.svn-base
字号:
if canusedebugregs then
begin
zeromemory(@zerobreak,sizeof(zerobreak));
zerobreak.ContextFlags:=CONTEXT_DEBUG_REGISTERS;
zerobreak.Dr7:=reg0set or reg1set or reg2set or reg3set;
for i:=0 to length(threadlist)-1 do
begin
suspendthread(threadlist[i,1]);
setthreadcontext(threadlist[i,1],zerobreak);
resumethread(threadlist[i,1]);
end;
end
else
begin
//temporarily disable all breakpoints
for i:=0 to length(int3userbreakpoints)-1 do
RewriteCode(processhandle,int3userbreakpoints[i].address,@int3userbreakpoints[i].originalbyte,1);
if int3CEBreakpoint.address>0 then
begin
RewriteCode(processhandle,int3CEbreakpoint.address,@int3cebreakpoint.originalbyte,1);
int3CEBreakpoint.address:=0;
end;
end;
end;
function TDebugger.handledebuggerplugins(devent:PDebugEvent):integer;
begin
{$ifndef net}
//go through the list of debugger plugins
result:=pluginhandler.handledebuggerplugins(devent);
{$endif}
end;
//I always knew viruses are usefull
function TDebugger.injectcode(AddressOfEntryPoint:dword;processhandle:thandle):dword;
{$ifndef net}
var LoadLibraryPtr: pointer;
GetProcAddressPtr: Pointer;
injectedlocation: pointer;
h: Thandle;
inject: array [0..255] of byte;
x:dword;
outp:TAssemblerBytes;
position,position2: dword;
dllLocation: string;
startaddresS: dword;
IHWCIloc: dword;
{$endif}
begin
{$ifndef net}
h:=LoadLibrary('Kernel32.dll');
if h=0 then raise exception.Create('No kernel32.dll loaded');
try
GetProcAddressPtr:=GetProcAddress(h,'GetProcAddress');
if getprocaddressptr=nil then raise exception.Create('GetProcAddress not found');
LoadLibraryPtr:=GetProcAddress(h,'LoadLibraryA');
if LoadLibraryptr=nil then raise exception.Create('LoadLibraryA not found');
injectedlocation:=VirtualAllocEx(processhandle,nil,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if injectedlocation=nil then raise exception.Create('Failed to allocate memory');
dlllocation:=extractfilepath(application.exename)+'CEHOOK.DLL';
position:=dword(injectedlocation);
position2:=0;
copymemory(@inject[0],pchar(dllLocation+#0),length(dllLocation)+1);
inc(position,length(dllLocation)+1);
inc(position2,length(dlllocation)+1);
ihwciloc:=position;
copymemory(@inject[position2],pchar('IHWCI'#0),6);
inc(position,6);
inc(position2,6);
startaddress:=position;
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;
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
{$ifndef net}
if handledebuggerplugins(@devent)=1 then
continue;
{$endif}
//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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -