Jump to content
Tuts 4 You

[Delphi] PEB Module Manipulation


abhe

Recommended Posts

Posted

just some function for manipulate module in PEB...


{ U_PEBModule
Author: Abhe
Description: Some manipulation Routine In PEB Ldr Data
Release Date: 23th april 2011
Website: http://cybercoding.wordpress.com/
}
unit U_PEBModule;interface
uses
windows,
sysutils,
JwaNative,
JwaNtStatus,
NcxNtTeb,
NcxNtDef;Procedure EnumPeb(ph:Thandle);
Function RemoteModuleHandle(ph : THandle; Modulename: PWidechar):DWord;
Function RemoteModuleImageName(ph,Mh : THandle):WideString;
Procedure RemotePatchModuleFileName(ph,mh : THandle; NewModulename: PWidechar);
Procedure UnlinkModule(ph,mh : THandle);
implementationtype
PROCESS_BASIC_INFORMATION = record
ExitStatus: Cardinal;
PebBaseAddress: PVOID;
AffinityMask: Cardinal;
BasePriority: Cardinal;
UniqueProcessId: Cardinal;
InheritedFromUniqueProcessId: Cardinal;
end;
TProcessBasicInformation = PROCESS_BASIC_INFORMATION;
PProcessBasicInformation = ^TProcessBasicInformation;function NtSuccess(AStatus: Longint): Boolean;
begin
Result := AStatus >= 0;
end;Procedure EnumPeb(ph:Thandle);
var
pbi : PROCESS_BASIC_INFORMATION;
PEB : TPeb32;
LdrData : TPebLdrData32;
LdrModule : TLdrDataTableEntry32;
i, dwread : DWord;
Head,Current : DWord;
BaseDllName : array[0..MAX_PATH] of widechar;
begin {Get PROCESS_BASIC_INFORMATION}
if not NtSuccess(ZwQueryInformationProcess(ph,ProcessBasicInformation,@pbi,SizeOf(pbi),@dwread)) then begin
OutputDebugString(Pchar('Failed Get PEB Location : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading PEB}
if not NtSuccess(ZwReadVirtualMemory(ph,pbi.PebBaseAddress,@PEB,sizeof(PEB),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading PEB : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading LoaderData}
if not NtSuccess(ZwReadVirtualMemory(ph,PEB.Ldr,@LdrData,sizeof(LdrData),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading LdrData : '+SysErrorMessage(Getlasterror)));
exit;
end; {init for enum the linked list}
i := 0;
Head := 0;
Current := DWord(LdrData.InLoadOrderModuleList.Flink); { loop for all ldr entry or module }
repeat {Reading Current entry}
if not NtSuccess(ZwReadVirtualMemory(ph,Ptr(Current),@LdrModule,sizeof(LdrModule),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading Current Module : '+SysErrorMessage(Getlasterror)));
break;
end; {Reading BaseDllName}
Fillchar(BaseDllName,sizeof(BaseDllName),0);
if not NtSuccess(ZwReadVirtualMemory(ph,LdrModule.BaseDllName.Buffer,@BaseDllName,LdrModule.BaseDllName.Length,@dwread)) then begin
OutputDebugString(Pchar('Failed Reading BaseDllName : '+SysErrorMessage(Getlasterror)));
end;
OutputDebugString(BaseDllName); {Next Module}
if i=0 then Head := Dword(LdrModule.InLoadOrderLinks.Blink);
Current := Dword(LdrModule.InLoadOrderLinks.Flink);
inc(i);
until Current = Head;
end;Function RemoteModuleHandle(ph : THandle; Modulename: PWidechar):DWord;
var
pbi : PROCESS_BASIC_INFORMATION;
PEB : TPeb32;
LdrData : TPebLdrData32;
LdrModule : TLdrDataTableEntry32;
i, dwread : DWord;
Head,Current : DWord;
BaseDllName : array[0..MAX_PATH] of widechar;
begin
result := 0; {Get PROCESS_BASIC_INFORMATION}
if not NtSuccess(ZwQueryInformationProcess(ph,ProcessBasicInformation,@pbi,SizeOf(pbi),@dwread)) then begin
OutputDebugString(Pchar('Failed Get PEB Location : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading PEB}
if not NtSuccess(ZwReadVirtualMemory(ph,pbi.PebBaseAddress,@PEB,sizeof(PEB),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading PEB : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading LoaderData}
if not NtSuccess(ZwReadVirtualMemory(ph,PEB.Ldr,@LdrData,sizeof(LdrData),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading LdrData : '+SysErrorMessage(Getlasterror)));
exit;
end; {init for enum the linked list}
i := 0;
Head := 0;
Current := DWord(LdrData.InLoadOrderModuleList.Flink); { loop for all ldr entry or module }
repeat {Reading Current entry}
if not NtSuccess(ZwReadVirtualMemory(ph,Ptr(Current),@LdrModule,sizeof(LdrModule),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading Current Module : '+SysErrorMessage(Getlasterror)));
break;
end; {Reading BaseDllName}
Fillchar(BaseDllName,sizeof(BaseDllName),0);
if not NtSuccess(ZwReadVirtualMemory(ph,LdrModule.BaseDllName.Buffer,@BaseDllName,LdrModule.BaseDllName.Length,@dwread)) then begin
OutputDebugString(Pchar('Failed Reading BaseDllName : '+SysErrorMessage(Getlasterror)));
end; {Check if this our target}
if (StrComp(LdrModule.BaseDllName.Buffer,Modulename) = 0) then begin
result := DWord(LdrModule.DllBase);
OutputDebugString(pchar(inttohex(result,8)));
break;
end; {Next Module}
if i=0 then Head := Dword(LdrModule.InLoadOrderLinks.Blink);
Current := Dword(LdrModule.InLoadOrderLinks.Flink);
inc(i);
until Current = Head;
end;Function RemoteModuleImageName(ph,Mh : THandle):WideString;
var
pbi : PROCESS_BASIC_INFORMATION;
PEB : TPeb32;
LdrData : TPebLdrData32;
LdrModule : TLdrDataTableEntry32;
i, dwread : DWord;
Head,Current : DWord;
BaseDllName : array[0..MAX_PATH] of widechar;
begin
result := ''; {Get PROCESS_BASIC_INFORMATION}
if not NtSuccess(ZwQueryInformationProcess(ph,ProcessBasicInformation,@pbi,SizeOf(pbi),@dwread)) then begin
OutputDebugString(Pchar('Failed Get PEB Location : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading PEB}
if not NtSuccess(ZwReadVirtualMemory(ph,pbi.PebBaseAddress,@PEB,sizeof(PEB),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading PEB : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading LoaderData}
if not NtSuccess(ZwReadVirtualMemory(ph,PEB.Ldr,@LdrData,sizeof(LdrData),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading LdrData : '+SysErrorMessage(Getlasterror)));
exit;
end; {init for enum the linked list}
i := 0;
Head := 0;
Current := DWord(LdrData.InLoadOrderModuleList.Flink); { loop for all ldr entry or module }
repeat {Reading Current entry}
if not NtSuccess(ZwReadVirtualMemory(ph,Ptr(Current),@LdrModule,sizeof(LdrModule),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading Current Module : '+SysErrorMessage(Getlasterror)));
break;
end; {Check if this our target}
if (DWord(LdrModule.DllBase) = mh) then begin {Reading BaseDllName}
Fillchar(BaseDllName,sizeof(BaseDllName),0);
if not NtSuccess(ZwReadVirtualMemory(ph,LdrModule.BaseDllName.Buffer,@BaseDllName,LdrModule.BaseDllName.Length,@dwread)) then begin
OutputDebugString(Pchar('Failed Reading BaseDllName : '+SysErrorMessage(Getlasterror)));
end; result := BaseDllName;
OutputDebugString(BaseDllName);
break;
end; {Next Module}
if i=0 then Head := Dword(LdrModule.InLoadOrderLinks.Blink);
Current := Dword(LdrModule.InLoadOrderLinks.Flink);
inc(i);
until Current = Head;
end;Procedure RemotePatchModuleFileName(ph,mh : THandle; NewModulename: PWidechar);
var
pbi : PROCESS_BASIC_INFORMATION;
PEB : TPeb32;
LdrData : TPebLdrData32;
LdrModule : TLdrDataTableEntry32;
i, dwread : DWord;
Head,Current : DWord;
pNewAddr : Pointer;
begin {Get PROCESS_BASIC_INFORMATION}
if not NtSuccess(ZwQueryInformationProcess(ph,ProcessBasicInformation,@pbi,SizeOf(pbi),@dwread)) then begin
OutputDebugString(Pchar('Failed Get PEB Location : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading PEB}
if not NtSuccess(ZwReadVirtualMemory(ph,pbi.PebBaseAddress,@PEB,sizeof(PEB),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading PEB : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading LoaderData}
if not NtSuccess(ZwReadVirtualMemory(ph,PEB.Ldr,@LdrData,sizeof(LdrData),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading LdrData : '+SysErrorMessage(Getlasterror)));
exit;
end; {init for enum the linked list}
i := 0;
Head := 0;
Current := DWord(LdrData.InLoadOrderModuleList.Flink); { loop for all ldr entry or module }
repeat {Reading Current entry}
if not NtSuccess(ZwReadVirtualMemory(ph,Ptr(Current),@LdrModule,sizeof(LdrModule),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading Current Module : '+SysErrorMessage(Getlasterror)));
break;
end; {Check if this our target}
if (DWord(LdrModule.DllBase) = mh) then begin { Get NewModule Name Length}
LdrModule.FullDllName.Length := lstrlenW(NewModulename) * 2; { Allocate Buffer to target process }
pNewAddr := nil;
if not NtSuccess(ZwAllocateVirtualMemory(ph, @pNewAddr, 0, @LdrModule.FullDllName.Length, MEM_COMMIT, PAGE_READWRITE)) then begin
OutputDebugString(Pchar('Failed Alloc Memory : '+SysErrorMessage(Getlasterror)));
exit;
end; { Write Our NewModulename to target process}
if not NtSuccess(ZwWriteVirtualMemory(ph, pNewAddr, NewModulename, LdrModule.FullDllName.Length, nil)) then begin
OutputDebugString(Pchar('Failed Write Our NewModulename : '+SysErrorMessage(Getlasterror)));
exit;
end; { set buffer to new address}
LdrModule.FullDllName.Buffer := pNewAddr;
OutputDebugString(LdrModule.FullDllName.Buffer); { write our LdrModule}
if not NtSuccess(ZwWriteVirtualMemory(ph, Ptr(Current), @LdrModule, sizeof(LdrModule), nil)) then begin
OutputDebugString(Pchar('Failed Write Our LdrModule : '+SysErrorMessage(Getlasterror)));
exit;
end; break;
end; {Next Module}
if i=0 then Head := Dword(LdrModule.InLoadOrderLinks.Blink);
Current := Dword(LdrModule.InLoadOrderLinks.Flink);
inc(i);
until Current = Head;
end;Procedure Unlink(ph : THandle; Link : TListEntry32);
var
Blink, Flink : DWord;
begin
Blink := Dword(Link.Blink);
Flink := Dword(Link.Flink); { write our flink in module blink}
ZwWriteVirtualMemory(ph, Ptr(Blink+DWord(@TListEntry32(nil^).Flink)), @Flink, sizeof(Flink), nil); { write our blink in module flink}
ZwWriteVirtualMemory(ph, Ptr(Flink+DWord(@TListEntry32(nil^).Blink)), @Blink, sizeof(Blink), nil);
end;Procedure UnlinkModule(ph,mh : THandle);
var
pbi : PROCESS_BASIC_INFORMATION;
PEB : TPeb32;
LdrData : TPebLdrData32;
LdrModule : TLdrDataTableEntry32;
i, dwread : DWord;
Head,Current : DWord;
begin {Get PROCESS_BASIC_INFORMATION}
if not NtSuccess(ZwQueryInformationProcess(ph,ProcessBasicInformation,@pbi,SizeOf(pbi),@dwread)) then begin
OutputDebugString(Pchar('Failed Get PEB Location : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading PEB}
if not NtSuccess(ZwReadVirtualMemory(ph,pbi.PebBaseAddress,@PEB,sizeof(PEB),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading PEB : '+SysErrorMessage(Getlasterror)));
exit;
end; {Reading LoaderData}
if not NtSuccess(ZwReadVirtualMemory(ph,PEB.Ldr,@LdrData,sizeof(LdrData),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading LdrData : '+SysErrorMessage(Getlasterror)));
exit;
end; {init for enum the linked list}
i := 0;
Head := 0;
Current := DWord(LdrData.InLoadOrderModuleList.Flink); { loop for all ldr entry or module }
repeat {Reading Current entry}
if not NtSuccess(ZwReadVirtualMemory(ph,Ptr(Current),@LdrModule,sizeof(LdrModule),@dwread)) then begin
OutputDebugString(Pchar('Failed Reading Current Module : '+SysErrorMessage(Getlasterror)));
break;
end; {Check if this our target}
if (DWord(LdrModule.DllBase) = mh) then begin { Unlink The linked list }
Unlink(ph,LdrModule.InLoadOrderLinks);
Unlink(ph,LdrModule.InMemoryOrderLinks);
Unlink(ph,LdrModule.InInitializationOrderLinks);
Unlink(ph,LdrModule.u1.HashLinks); break;
end; {Next Module}
if i=0 then Head := Dword(LdrModule.InLoadOrderLinks.Blink);
Current := Dword(LdrModule.InLoadOrderLinks.Flink);
inc(i);
until Current = Head;
end;end.

and example use

var
h : THandle;
begin
EnumPeb(thandle(-1));
h := RemoteModuleHandle(thandle(-1),'Project1.exe');
RemoteModuleImageName(thandle(-1),h);
RemotePatchModuleFileName(thandle(-1),h,pchar(paramstr(0)+'asadasdsa'));
messagebox(0,pchar(paramstr(0)),nil,mb_ok);
UnlinkModule(thandle(-1),h);
EnumPeb(thandle(-1));
end.

btw u need this unit by Nico Bendlin

http://www.bendlins.de/nico/delphi/NcxWOW64.zip

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...