if Address = OldAddress then
begin
EnterCriticalSection(CritSect);
if VirtualProtect(Address, sizeof(Address),PAGE_EXECUTE_READWRITE, @dwOldProtect) then
try
WriteProcessMemory(GetCurrentProcess, ImportCode, @NewAddress, SizeOf(dword), BytesWritten);
finally
VirtualProtect(Address, sizeof(Address),dwOldProtect, nil);
LeaveCriticalSection(CritSect);
end;
end;
Inc(ImportCode);
end;
Inc(ImageImportEntry);
end;
end;
Is there something I can test to make sure its writing correctly to right address?
The hook simply does not work. It finds all the imported modules even seems to be writing something because Ive done
byteswritten :=0
VirtualProtect(Address, sizeof(Address),PAGE_EXECUTE_READWRITE, @dwOldProtect) then
WriteProcessMemory(GetCurrentProcess, ImportCode, @NewAddress, SizeOf(dword), BytesWritten);
if byteswritten > 0 then
messagebox(0,'written','test',0);
(and i get the msg box.)
I have not seen another api for writing to the IAT accept CopyMemory(). I have tried that too but the params are wrong because it crashes.
CopyMemory(Address, NewAddress,5); ???
Yes Ive used your collection and it works perfectly but its just a little bulky and I need something smaller and simple.
This function works fine. For successful IAT patching you need to patch each and every module in your process. However, in win9x you're not allowed to patch system modules (modules whose handle is bigger than $80000000). If you would do that, you'd make the whole OS unstable. As a result IAT patching doesn't work too well in win9x. After all IAT patching is not the best hooking method. But in normal use you might not notice the difference. It depends on for which purpose you need this stuff.
procedure PatchImportTable(module: dword; old, new: pointer);
var pinh : PImageNtHeaders;
pid : ^TImageImportDirectory;
p1 : TPPointer;
c1 : dword;
eis : dword; // end of import section
begin
pinh := GetImageNtHeaders(module);
if pinh <> nil then begin
with pinh^.OptionalHeader.DataDirectory[IMAGE
pid := pointer(module + VirtualAddress);
eis := VirtualAddress + Size;
end;
if pid <> nil then
while pid^.Name_ <> 0 do begin
if pid^.ThunkArray > eis then
break; // invalid import table!
if pid^.ThunkArray <> 0 then begin
p1 := pointer(module + pid^.ThunkArray);
while p1^ <> nil do begin
if (p1^ = old) and VirtualProtect(p1, 4, PAGE_EXECUTE_READWRITE, @c1) then
p1^ := new;
inc(p1);
end;
end;
inc(pid);
end;
end;
end;
===============================
Okay, the reason for the failure is very probably that you missed what I said here:
"For successful IAT patching you need to patch each and every module in your process. However, in win9x you're not allowed to patch system modules (modules whose handle is bigger than $80000000)"
Patching just the main module (GetModuleHandle(nil)) isn't enough. You have to loop through all modules and patch each and every one (except the system modules in win9x).
Aphex code must do that internally, too, if it works correctly. So I guess you can use his dll enumeration code together with my patching function.
madCodeHook uses a completely different approach.
His code looks more or less alright. The WriteProcessMemory call is a bit strange, but it should work nevertheless.
There are 2 possible reasons why his unit fails on 9x. Either you need to hook dynamically loaded dlls, too. Or import table patching is just not good enough in this specific situation.
Try this:
type
TDAModule = array of cardinal;
// returns all modules of the current process
function GetModuleList : TDAModule;
var p1, p2 : pointer;
mbi : TMemoryBasicInformation;
arrCh : array [0..MAX_PATH] of char;
i1 : integer;
begin
SetLength(result, 10);
i1 := 0;
p1 := nil;
p2 := nil;
while VirtualQueryEx(GetCurrentProcess, p1, mbi, sizeOf(mbi)) = sizeOf(mbi) do begin
if (mbi.State = MEM_COMMIT) and
(mbi.AllocationBase <> p2) and (mbi.AllocationBase = mbi.BaseAddress) and
(GetModuleFileName(dword(mbi.AllocationB
if i1 = Length(result) then
SetLength(result, i1 * 2);
result[i1] := dword(mbi.AllocationBase);
inc(i1);
end;
p2 := mbi.AllocationBase;
dword(p1) := dword(p1) + mbi.RegionSize;
end;
SetLength(result, i1);
end;
procedure PatchImportTables(old, new: pointer);
var i1 : integer;
modules : TDAModule;
begin
modules := GetModuleList;
for i1 := 0 to high(modules) do
if (GetVersion and $80000000 = 0) or (modules[i1] < $80000000) then
PatchImportTable(modules[i1], old, new);
end;
Then call PatchImportTables instead of PatchImportTable. This will hook all modules of the current process (excluding the system modules in 9x).
P.S: Please instead of "@FindNextFileW" use "GetProcAddress(kmodule, 'FindNextFileW')". Furthermore in win9x please run your exe *outside* of the IDE. In XP you can run it inside or outside.
I explain. You put your DLL-loading code into the remote process, probably using WriteProcessMemory(). Then you set the topExcFilter of that process to something that points into the code you just injected (in case it goes wrong or something) and save the old value, of course. Now you repeatedly try to start your remote thread in the process, until it returns no error. No bother if an access violation occurs, because your exception code will handle it to pass silently. In your code, you call LoadLibrary(), load your DLL then finally un-set the exception filter.
MSDN Library says though that calling LoadLibrary() from within DllMain() is not safe, I guess that may apply if the process is not initialized. A quick hack you can do, though, is, from the second thread, constantly monitor the main thread's EIP value, and, and as soon as it is in the range 0x00400000-(end of the executable), load your DLL.
I wonder what's the precise use of your DLL anyway. Maybe there's another way to achieve the same result anyway.
Here's an odd, but probably working (not depending on LoadLibrary()) idea:
If you absolutely need to inject code in the process, you can probably just manually allocate pages into it, then write only the code (no PE image, only the code) which, at it's beginning, would contain a table of all DLL functions that are used, and that you would patch before injecting the code, finding every of the functions' addresses using GetProcAddress(). Of course your code, unless it was specifically written (probably in assembly) to be run as PIC, will need to always be at a specific location.
That just gave me a better, simpler idea:
Why don't you have the loader process (the one that injects the DLL into the other processes) load your DLL into the 0x80000000-0xBFFFFFFF shared area? That would probably need a bit of tweak but, after, your DLL would be loaded for ALL processes :-)
That's all the ideas I'd got for now. I hope this may help you
There are some system and/or third party dlls, which have a thread dependent initialization. The first time their entry point gets called, they think: "Welcome, main thread!!". Now if I create my remote thread too early, those dlls think that the remote thread is the main thread. As a result crashes or wild reactions will happen.
Creating the remote thread itself is not the problem, it does work. Just the consequences (I described above) are the problem.
>> I wonder what's the precise use of your DLL anyway. Maybe there's another way to achieve the same result anyway.
I'm currently working on "madCodeHook 2.0", which will feature system wide dll injection for both 9x and NT. Here you can find the documentation of "madCodeHook 1.0": http:
>> Here's an odd, but probably working (not depending on LoadLibrary()) idea:
madCodeHook has a function named "CopyFunction", which can easily just copy a function to another process - including all necessary relocations. I'm already making use of such hacks quite often internally in madCodeHook. But doing such stuff is not that easy and the function you copy has to follow quite special rules. Most of my customers can't do things like that. They just want to call "InjectLibrary(SYSTEM_WIDE, "their.dll")" and they want madCodeHook to do the rest for them.
>> That just gave me a better, simpler idea:
>> Why don't you have the loader process (the one that injects the DLL into the other processes) load your DLL into the 0x80000000-0xBFFFFFFF shared area? That would probably need a bit of tweak but, after, your DLL would be loaded for ALL processes :-)
Such a shared DLL needs some special tweaking. E.g. (IIRC) it must have shared data segments only. This can make quite some problems. And in Delphi you can't even create such DLLs (without manually hacking the PE structure, that is). So again it's too difficult for my customers.
madCodeHook is supposed to take *any* DLL and inject it into all current and future processes in any OS. And I have to make that work. Well, it does work. As I wrote some comments earlier I've implemented an ugly but (more or less) working solution for my last remaining problem (injection into already running processes in 9x). But I'd still like to have it solved a bit cleaner.
2232



被折叠的 条评论
为什么被折叠?



