inject的讨论

Now Aphex made a hooking unit(afxCodeHook) in delphi but sadly it only works on NT systems.  I can inject the library fine in win9x using elicz elirt library.  But actually writing to the import address table seems to be a problem.  Ive tried to fix it by changing the protection attributes but it didnt do much.  Here is the section where it fails:

        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?
================
Thank you for replying.  Ive added in critical section because some hooking tutorials/examples (like some from rootkit.com) do that so no other threads can access the memory page while you are writing to it. Its just some things ive have been trying to make work on 9x.  

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.
====================
You can use the following code, it's copied from my madExcept package. madCodeHook uses a much better but also much more complicated API hooking method. The missing parts (e.g. GetImageNtHeaders) can be found in the madBasic package (which includes sources) of my collection.

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 _DIRECTORY _ENTRY_IMP ORT] do begin
      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;
===============================
Ah, finally I get to see some details...   :-)

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.
==============================
An API is exported by one module (module = dll or exe). E.g. FindNextFileW is exported by kernel32.dll. Each process contains of one exe module and several dll modules, which are either dynamically or statically linked by the exe module. Now each of the dll module may have imported FindNextFileW. If e.g. "user32.dll" calls "FindNextFileW", your only chance the get notification about this is by patching the import table of "user32.dll". In other words: You have to patch the import table of all modules (exe + dlls) in your process. That is the very base logic of import table patching.

madCodeHook uses a completely different approach.
=================================
I've just looked at his code. He does not enumerate the modules of the process. But when patching the import table he checks for dlls which are listed in the import table and hooks those, too. That means he hooks all dlls, which are statically linked. But he does not hook dynamically linked dlls.

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 ase), arrCh, MAX_PATH) > 0) then begin
      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.
====================
Maybe, instead of trying to determine clearly if a process is initialized, you could simply repeatedly try to create your remote thread until it succeeds, using SetUnhandledExceptionFilter() to catch any access violations that may occur?

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
=============================
>> Maybe, instead of trying to determine clearly if a process is initialized, you could simply repeatedly try to create your remote thread until it succeeds, using SetUnhandledExceptionFilter() to catch any access violations that may occur?

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://help.madshi.net/madCodeHook.htm . It's an "API hooking" + "DLL injection" package which other programmers can use.

>> 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.
// madCodeHook.pas version: 2.0 ? date: 2003-08-10 // ---------- // API hooking, code hooking // ---------- // Copyright (C) 1999 - 2003 www.madshi.net, All Rights Reserved // ********** // 2003-08-10 2.0 (1) HookCode parameters changed -> only one flags parameter // (2) (Un)InjectLibrary: user/session/system wide injection! // (3) InjectLibrary2 replaced by InjectLibrary (auto detect) // (4) static lib for Microsoft C++ added // (5) CreateIpcQueue + SendIpcMessage + DestroyIpcQueue added // (6) AmSystemProcess + AmUsingInputDesktop added // (7) GetCurrentSessionId + GetInputSessionId added // (8) GetCallingModule function added // (9) ProcessIdToFileName added // (a) Create/OpenGlobalMutex + Event + FileMapping added // (b) WideToAnsi + AnsiToWide functions added // (c) RenewHook function added // (d) madCodeHook.dll -> madCHook.dll (8.3 dos name logic) // (e) UnhookAPI added (= UnhookCode, added just for the look) // (f) AddAccessForEveryone added // 2002-10-17 1.3f InjectLibrary2(W) was not stdcall (dumb me) // 2002-10-03 1.3e (1) InjectLibraryW added // (2) InjectLibrary2(W) added for use in CreateProcess(W) hooks // 2002-09-22 1.3d CreateProcessExW added // 2002-03-24 1.3c CollectHooks/FlushHooks speed up mixture initialization // 2002-02-24 1.3b LPSTARTUPINFO -> LPSTARTUPINFOA // 2002-01-21 1.3a ProcessHandleToId exported // 2001-07-08 1.3 new functions (1) AllocMemEx & FreeMemEx // (2) CopyFunction // (3) CreateRemoteThread and // (4) InjectLibrary added // 2001-04-20 1.2a you can now force HookCode/API to use the mixture mode // 2001-04-16 1.2 new function CreateProcessEx -> dll injecting
在JavaScript中,"inject"一词通常与注入攻击相关,但在非安全相关的上下文中,它可能仅仅指将代码注入到另一个环境中执行。如果我们讨论的是在网页环境中通过JavaScript注入代码来修改页面内容或行为,这通常涉及到使用JavaScript来动态地修改DOM(文档对象模型)。 在网页中,DOM是一种以树形结构表示HTML文档的编程接口,允许JavaScript与页面上的元素进行交互。通过DOM操作,可以动态地添加、修改或删除网页的内容、结构和样式。例如,可以使用以下JavaScript代码片段在页面上添加新的元素或者修改现有的元素: ```javascript // 创建一个新的元素 var newDiv = document.createElement('div'); // 设置新元素的内容 newDiv.innerHTML = '这是新添加的内容'; // 将新元素添加到页面中的某个父元素内 document.getElementById('parentElementId').appendChild(newDiv); // 修改页面上某个已存在的元素 document.getElementById('existingElementId').textContent = '修改后的内容'; ``` 修改DOM的行为可能会因为用户的交互而触发,也可能因为执行了某些脚本而自动触发。常见的修改方式包括但不限于: 1. `document.createElement`:创建一个新的DOM元素。 2. `document.getElementById`、`document.querySelector` 等:选取页面中的元素。 3. `appendChild`、`insertBefore` 等:将元素添加到DOM中。 4. `removeChild`、`replaceChild` 等:从DOM中移除或替换元素。 5. `innerHTML`、`textContent`、`setAttribute` 等:修改元素的内容或属性。 进行DOM操作时需要注意安全性和性能问题,比如避免跨站脚本攻击(XSS)和确保操作不会影响到页面的性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值