📄 dbk32functions.pas
字号:
unit DBK32functions;
interface
uses windows,sysutils,winsvc,psapi,classes,types,registry;
//xp sp2
//ThreadsProcess=220
//ThreadListEntry=22c
const currentversion=2000007;
const FILE_ANY_ACCESS=0;
const FILE_SPECIAL_ACCESS=FILE_ANY_ACCESS;
const FILE_READ_ACCESS=$0001;
const FILE_WRITE_ACCESS=$0002;
const METHOD_BUFFERED= 0;
const METHOD_IN_DIRECT= 1;
const METHOD_OUT_DIRECT= 2;
const METHOD_NEITHER= 3;
const FILE_DEVICE_UNKNOWN=$00000022;
const IOCTL_UNKNOWN_BASE=FILE_DEVICE_UNKNOWN;
type thandlelist=record
processhandle: thandle;
processid: dword;
validhandle: boolean;
end;
type TClient_ID=record
processid: thandle;
threadid: thandle;
end;
type PClient_ID=^TClient_ID;
type THookIDTThread=class(tthread)
public
cpunr: byte;
done: boolean;
succeeded: boolean;
procedure execute; override;
end;
type THookIDTConstantly=class(tthread)
public
procedure execute; override;
end;
var cpuidt: array of dword;
type TGetIDTThread=class(tthread)
public
cpunr: byte;
done: boolean;
procedure execute; override;
end;
var hdevice: thandle; //handle to my the device driver
handlelist: array of thandlelist;
driverloc: string;
iamprotected:boolean;
SDTShadow: DWORD;
debugport,processname: dword;
ThreadsProcess,ThreadListEntry:dword;
processeventname, threadeventname: string;
processevent,threadevent:thandle;
ownprocess: thandle; //needed for simple kernelmemory access
Successfullyloaded:boolean;
usealternatedebugmethod: boolean;
function CTL_CODE(DeviceType, Func, Method, Access : integer) : integer;
function IsValidHandle(hProcess:THandle):BOOL; stdcall;
Function {OpenProcess}OP(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwProcessId:DWORD):THANDLE; stdcall;
Function {OpenThread}OT(dwDesiredAccess:DWORD;bInheritHandle:BOOL;dwThreadId:DWORD):THANDLE; stdcall;
function {ReadProcessMemory}RPM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
function {WriteProcessMemory}WPM(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
function {VirtualQueryEx}VQE(hProcess: THandle; address: pointer; var mbi: _MEMORY_BASIC_INFORMATION; bufsize: DWORD):dword; stdcall;
Function {NtOpenProcess}NOP(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
Function {NtOpenThread}NtOT(var Handle: THandle; AccessMask: dword; objectattributes: pointer; clientid: PClient_ID):DWORD; stdcall;
Function {VirtualAllocEx}VAE(hProcess: THandle; lpAddress: Pointer; dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;
Function CreateRemoteAPC(threadid: dword; lpStartAddress: TFNAPCProc): THandle; stdcall;
function DBKGetDC(window: HWND): HDC;
Function GetPEProcess(ProcessID: dword):dword; stdcall;
Function GetPEThread(Threadid: dword):dword; stdcall;
function GetDebugportOffset: DWORD; stdcall;
function GetProcessnameOffset: dword; stdcall;
function GetThreadsProcessOffset: dword; stdcall;
function GetThreadListEntryOffset: dword; stdcall;
function ReadPhysicalMemory(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesRead:DWORD):BOOL; stdcall;
function WritePhysicalMemory(hProcess:THANDLE;lpBaseAddress:pointer;lpBuffer:pointer;nSize:DWORD;var NumberOfBytesWritten:DWORD):BOOL; stdcall;
function GetPhysicalAddress(hProcess:THandle;lpBaseAddress:pointer;var Address:int64): BOOL; stdcall;
function ProtectMe(ProtectedProcessID: dword; denylist,globaldenylist:BOOL;list:pchar; listsize:dword):BOOL; stdcall; //or should I give it a array of processid's?
function UnprotectMe:bool; stdcall;
function GetCR4:DWORD; stdcall;
function GetCR3(hProcess:THANDLE;var CR3:DWORD):BOOL; stdcall;
function SetCR3(hProcess:THANDLE;CR3: DWORD):BOOL; stdcall;
function GetSDT:DWORD; stdcall;
function GetSDTShadow:DWORD; stdcall;
function setAlternateDebugMethod(var int1apihook:dword; var OriginalInt1handler:dword):BOOL; stdcall;
function getAlternateDebugMethod:BOOL; stdcall;
function DebugProcess(processid:dword;address:DWORD;size: byte;debugtype:byte):BOOL; stdcall;
function StopDebugging:BOOL; stdcall;
function StopRegisterChange(regnr:integer):BOOL; stdcall;
function RetrieveDebugData(Buffer: pointer):integer; stdcall;
function ChangeRegOnBP(Processid:dword; address: dword; debugreg: integer; changeEAX,changeEBX,changeECX,changeEDX,changeESI,changeEDI,changeEBP,changeESP,changeEIP,changeCF,changePF,changeAF,changeZF,changeSF,changeOF:BOOLEAN; newEAX,newEBX,newECX,newEDX,newESI,newEDI,newEBP,newESP,newEIP:DWORD; newCF,newPF,newAF,newZF,newSF,newOF:BOOLEAN):BOOLEAN; stdcall;
function StartProcessWatch:BOOL;stdcall;
function WaitForProcessListData(processpointer:pointer;threadpointer:pointer;timeout:dword):dword; stdcall;
function GetProcessNameFromPEProcess(peprocess:dword; buffer:pchar;buffersize:dword):integer; stdcall;
function GetProcessNameFromID(processid:dword; buffer:pointer;buffersize:dword):integer; stdcall;
function MakeWritable(Address,Size:dword;copyonwrite:boolean): boolean; stdcall;
function RewriteKernel32:boolean; stdcall;
function RestoreKernel32:boolean; stdcall;
function InitializeDriver(Address,size:dword):BOOL; stdcall;
function GetWin32KAddress(var address:DWORD;var size:dworD):boolean;
function GetDriverVersion: dword;
function GetIDTCurrentThread:dword; stdcall;
function GetIDTs(idtstore: pointer; maxidts: integer):integer; stdcall;
function GetLoadedState: BOOLEAN; stdcall;
function test: boolean; stdcall;
procedure useIOCTL(use: boolean); stdcall;
function DBKSuspendThread(ThreadID:dword):boolean; stdcall;
function DBKResumeThread(ThreadID:dword):boolean; stdcall;
function DBKSuspendProcess(ProcessID:dword):boolean; stdcall;
function DBKResumeProcess(ProcessID:dword):boolean; stdcall;
function KernelAlloc(size: dword):pointer; stdcall;
function GetKProcAddress(s: pwidechar):pointer; stdcall;
function Protect2(var testprotect:dword; var NewObOpenObjectByPointer: dword; var OriginalObOpenObjectByPointer: dword):boolean; stdcall;
var hooker: THookIDTConstantly;
kernel32dll: thandle;
ioctl: boolean;
implementation
procedure FSC;
asm
mov edx,esp
sysenter
end;
function GetLoadedState: BOOLEAN; stdcall;
begin
result:=(hdevice<>INVALID_HANDLE_VALUE) and Successfullyloaded;
end;
procedure useIOCTL(use: boolean); stdcall;
begin
ioctl:=use;
end;
function Test:boolean; stdcall;
{$W+}
procedure test_noioctl(p1:integer; p2: integer); stdcall;
asm
pop ebp //used parameters so the stupid compiler added a push ebp
mov eax,$2000
call fsc
ret 8
end;
{$W-}
var cc,br: dword;
threadid: dword;
begin
result:=true;
if ioctl then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0804, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
result:=deviceiocontrol(hdevice,cc,@threadid,sizeof(threadid),nil,0,br,nil);
end
else
begin
test_noioctl(1,2);
end;
end;
function GetIDTCurrentThread:dword;
var cc,br: dword;
idtdescriptor: packed record
wLimit:word;
vector: dword;
end;
begin
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080f, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
deviceiocontrol(hdevice,cc,nil,0,@idtdescriptor,6,br,nil);
result:=idtdescriptor.vector;
end else result:=0;
end;
procedure TGetIDTThread.execute;
begin
try
cpuidt[cpunr]:=getidtcurrentthread;
finally
done:=true;
end;
end;
function GetIDTs(idtstore: pointer; maxidts: integer):integer; stdcall;
var ec: dword;
i:integer;
cpunr,PA,SA:Dword;
cpunr2:byte;
begin
//max idt's should be 32, but may be less if you('re a retard!) don't want to allocate the enormous ammount of 32*4=128 bytes
setlength(cpuidt,0);
result:=0; //0 idt's returned
if hdevice<>INVALID_HANDLE_VALUE then
begin
GetProcessAffinityMask(getcurrentprocess,PA,SA);
//first hook the interrupts if needed
cpunr2:=0;
cpunr:=1;
while (cpunr<=PA) do
begin
if ((cpunr) and PA)>0 then
begin
setlength(cpuidt,length(cpuidt)+1);
SetProcessAffinityMask(getcurrentprocess,cpunr);
//create a new thread. (Gues on what cpu it will run at...)
with TGetIDTThread.Create(true) do
begin
try
cpunr:=cpunr2;
resume;
while not done do sleep(20); //the sleep should also cause a taskswitch but I'm not 100% sure
finally
free;
end;
end;
end;
if cpunr=$80000000 then break;
inc(cpunr,cpunr);
inc(cpunr2);//next cpu
end;
SetProcessAffinityMask(getcurrentprocess,PA); //multi processors are so fun. It'd be a waste not to use it
for i:=0 to length(cpuidt)-1 do
TCardinalDynArray(idtstore)[i]:=cpuidt[i];
result:=length(cpuidt);
end;
end;
procedure THookIDTThread.execute;
var cc,br: dword;
begin
try
// outputdebugstring('hooking IDT');
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0810, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
succeeded:=deviceiocontrol(hdevice,cc,@cpunr,1,@cpunr,0,br,nil);
finally
done:=true;
end;
end;
procedure THookIDTConstantly.execute;
var input:TInput;
br,cc: dword;
i:integer;
cpunr,PA,SA:Dword;
cpunr2:byte;
begin
freeonterminate:=true;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0810, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
while not terminated do
begin
// outputdebugstring('writing the idt');
GetProcessAffinityMask(getcurrentprocess,PA,SA);
cpunr2:=0;
cpunr:=1;
while (cpunr<=PA) do
begin
if ((cpunr) and PA)>0 then
begin
SetProcessAffinityMask(getcurrentprocess,cpunr);
//create a new thread. (Gues on what cpu it will run at...)
with THookIDTThread.Create(true) do
begin
try
cpunr:=cpunr2;
resume;
while not done do sleep(10); //the sleep should also cause a taskswitch but I'm not 100% sure
finally
free;
end;
end;
end;
if cpunr=$80000000 then break;
inc(cpunr,cpunr);
inc(cpunr2);
end;
SetProcessAffinityMask(getcurrentprocess,PA); //multi processors are so fun. It'd be a waste not to use it
sleep(5000); //wait a while before rewriting
end;
end;
end;
function GetProcessNameFromPEProcess(peprocess:dword; buffer:pchar;buffersize:dword):integer; stdcall;
var ar:dword;
i:integer;
begin
if buffersize>16 then buffersize:=16;
result:=-1;
if processname=0 then exit;
if (hdevice<>INVALID_HANDLE_VALUE) and (ownprocess<>0) then
begin
if rpm(ownprocess,pointer(peprocess+processname),buffer,buffersize,ar) then
begin
for i:=0 to buffersize-1 do
if buffer[i]=#0 then
begin
result:=i+i;
exit;
end;
end;
end;
end;
function GetCR4:DWORD; stdcall;
var x,res,cc:dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0817, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@res,4,@res,4,x,nil) then
result:=res;
end;
end;
function GetDriverVersion:dword;
var x,res,cc:dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $0816, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@res,4,@res,4,x,nil) then
result:=res;
end;
end;
function GetProcessNameFromID(processid:dword; buffer:pointer;buffersize:dword):integer; stdcall;
begin
//just a simple stub
result:=GetProcessNameFromPEProcess(GetPEProcess(processid),buffer,buffersize);
end;
function GetThreadsProcessOffset: dword; stdcall;
begin
result:=ThreadsProcess;
end;
function GetThreadListEntryOffset: dword; stdcall;
begin
result:=ThreadListEntry;
end;
function GetProcessnameOffset: dword; stdcall;
begin
result:=processname;
end;
function GetDebugportOffset: DWORD; stdcall;
begin
result:=debugport;
end;
function GetSDTShadow:DWORD; stdcall;
begin
result:=SDTShadow;
end;
function GetSDT:DWORD; stdcall;
var res,x,cc:dword;
begin
result:=0;
if hdevice<>INVALID_HANDLE_VALUE then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080c, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
if deviceiocontrol(hdevice,cc,@res,4,@res,4,x,nil) then
result:=res;
end;
end;
function GetCR3(hProcess:THANDLE;var CR3:DWORD):BOOL; stdcall;
var cc:dword;
x,y:dword;
i: integer;
begin
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080a, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
x:=handlelist[i].processid;
result:=deviceiocontrol(hdevice,cc,@x,4,@x,4,y,nil);
if result then CR3:=x else cr3:=$11223344;
end;
end;
end;
function SetCR3(hProcess:THANDLE;CR3: DWORD):BOOL; stdcall;
var cc:dword;
ar: array [0..7] of byte;
x:dword;
i: integer;
begin
result:=false;
if hdevice<>INVALID_HANDLE_VALUE then
begin
for i:=0 to length(handlelist)-1 do
if handlelist[i].processhandle=hProcess then
begin
cc:=CTL_CODE(IOCTL_UNKNOWN_BASE, $080b, METHOD_BUFFERED, FILE_READ_ACCESS or FILE_WRITE_ACCESS);
pdword(@ar[0])^:=handlelist[i].processid;
pdword(@ar[4])^:=CR3;
result:=deviceiocontrol(hdevice,cc,@ar[0],4,@ar[0],4,x,nil);
end;
end;
end;
function ProtectMe(ProtectedProcessID: dword; denylist,globaldenylist:BOOL;list:pchar; listsize:dword):BOOL; stdcall; //or should I give it a array of processid's?
type tinput=record
processid: dword;
DenyList: DWORD;
GlobalDenyList: DWORD;
ListSize:DWORD;
end;
var cc,x: dword;
input: ^tinput;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -