Page 1 of 2 12 LastLast
Results 1 to 15 of 20

Thread: Modifying NTDLL ?

  1. #1

    Modifying NTDLL ?

    Is it possible to modify NTDLL and reboot ?

    Can anyone suggest any pointers or resources to making modifications to NTDLL ?

    I'm not after other peoples snippets of the change they made to fulfill some requirement, but a broader overview of the concerns with simply making a modifications to NTDLL. Things to be aware of, things to check for, etc...

    Things I can contribute:
    * Have a way to recover the system (bootable ISO / USBdisk with something like BartPE is one easy way)
    * Don't use your own workstation have a 2nd PC.
    * Ensure you always fixup the PE header checksum.

    As you can see my knowledge soons runs out. The purpose of my interest is to have more control over anti-debugging measures without using ring-0.

    One other question concerning NTDLL there are exported functions NtXXXX and ZwXXXX the NtXXXX series I understand are called from the user-mode context where the state of the machine is exactly the same as a the application.

    I'd like to understand more about the ZwXXXX series of functions and the transitions between the two machine states. For example is the "FS" segment register which is used by user-mode to point to the Thread Local Storage (TIB/TEB), is it loaded with the same value for all contexts that ZwXXXX calls are made ?

    Some of the anti-debugging area of interest have aliased implementations ("aliased" meaning 2 or more Export Address Table entries pointing to the same implementation of a function, since it is shared by the NtXXXX and the ZwXXXX series).

  2. #2
    <script>alert(0)</script> disavowed's Avatar
    Join Date
    Apr 2002
    NtXXXX should be called from user-mode context. ZwXXXX should be called from kernel-mode context. For many functions they do the same thing, but for some, ZwXXXX makes certain assumptions.

    What kind of anti-debugging measures are you looking to have more control over that you expect modifying NTDLL.DLL will help with?

  3. #3
    In user-mode :
    ZwXxx == NtXxx
    FS points to TEB (Thread Environment Block)

    In kernel-mode :
    ZwXxx != NtXxx
    ZwXxx should be used always .
    Most of NtXxx could be called when PreviousMode == KernelMode and passed buffers exist in kernel space .
    FS points to KPCR (Current Processor Control Region)

  4. #4
    Quote Originally Posted by disavowed View Post
    What kind of anti-debugging measures are you looking to have more control over that you expect modifying NTDLL.DLL will help with?
    For starters:

    NtQueryInformationProcess(..., ProcessDebugPort, ..., ..., ...)
    NtSetInformationThread(..., ThreadHideFromDebugger, ..., ...)

    Both of these method (and their ZwXXXX aliases) in the platform I am working on (WinXP SP2) directly invoke a system call entry. I have written a tiny interceptor

    The implementation for these functions also have around 6 "NOP" instructions padding the call, the entrypoint of the function is not even aligned to any nice boundary. If there a reason for the padding ?

    In order to fit my small intercept in I had to relocate the previous function to bunch them up to gain the 3 lots of 6xNOP instructions. I fixed up EAT and only one of the 4 affected methods is being called internally from part code in .text so those 32DISP were also fixed up to the new address. The added code in the .text us simply using up the 0x00 padding currently in the file already and extending the section size in the section header a little (I have not needed to extend the file length and move up all the segments). But I still have not gotten it to successfully bootup.

    I am making use of FS segment register for TEB and then PEB access, knowing these same methods are also ZwXXXXX implementations. The use of it is basically an interception switch (I wanted to use $0x7ffe0e08 but that page is readonly) so I opted for PEB but now I shall opt for extending the .data section using a location there. (since the FS segment is different for some contents in which ZwXXXXX is being called).

    Is there any glaring problem with what I am trying to achieve ? Should it be possible to make these kinds of modifications (at the moment it auto-reboots during startup, but I've not attempted many tries yet still much to learn).

    Does anyone know if any other part of the OS or core DLL/SYS makes assumptions (esp with regards to NOP padding and expected load address for the moved functions) ? or anything I have overlooked that also needs some kind of fixup ?

    Thanks for your replies all.

  5. #5
    Musician member evaluator's Avatar
    Join Date
    Sep 2001
    Blog Entries
    proper way is driver-hook. because you need to control, when hide - when not.

  6. #6
    Quote Originally Posted by evaluator View Post
    proper way is driver-hook. because you need to control, when hide - when not.
    Thanks for the reply, but proper way in what sense ? Yes I understand a ring0 approach would be the next step but it mitigates a few points:

    1) It deprives me of the learning curve associated with this approach.
    2) My intercept inside NTDLL already has code/logic in it to enable/disable under my control.
    3) I have the ability to run Win32 code under a form of emulation outside of a Win32 system, this allows me to perform intercepts and overwrites of data/code that are just not possible to do inside a Win32 environment (since the program would crash or just not behave correctly).
    4) I have been able to verify/debug my modifications to NTDLL under this emulation in the context of the target application being run, so this presumes I can get the machine to boot (which means all other users of NTDLL needs to be happy with my modifications too, I hope to spend some more time on it later today and report back my woes, I bet it's due to my use of FS segment register access when called from ZwXXXX context).

    PS. I forgot to add, the emulation doesn't emulate ring0 stuff hence why a user-space solution is being pursued because my main reversing technique is not actually done under / inside a Win32 system at all.
    Last edited by Nido; May 21st, 2009 at 07:21. Reason: Clarification

  7. #7
    Musician member evaluator's Avatar
    Join Date
    Sep 2001
    Blog Entries
    then, are under you control NTDLL-file-content check!?

    & in generic, modifying system file is incorrect approach ~:~

  8. #8
    Quote Originally Posted by evaluator View Post
    then, are under you control NTDLL-file-content check!?

    & in generic, modifying system file is incorrect approach ~:~
    I do not understand your cryptic response. Maybe english is not your 1st language. Please have another go.

  9. #9
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    Have you disabled or otherwise modified Windows File Protection (WFP) so the changed ntdll isn't detected?

    This may be what evaluator was alluding to. His responses are almost always purposely cryptic, but almost always useful as well. Consider them reversing challenges obfuscating some nugget of information.

  10. #10
    |< x != '+' BanMe's Avatar
    Join Date
    Oct 2008
    Farmington NH
    Blog Entries
    WFP may not need to be bypassed to implement such a solution.. a dll proxy and Peb hooking could do the job at runtime instead of directly modifying the file and having to bypass WFP

    PEB Hooking article on phrack

    Dll Proxy generator can be found on CodeProject

    Regards BanMe

  11. #11
    Thanks for the pointer on WFP, I wasn't aware the mechanism existed, I am 100% happy to disable it since the host machine's only purpose is to assist inspection of the target (It can be reinstalled in 15mins should it be really screwed up). Would I be correct in presuming that with WFP alarms go off I get some form of Microsoft message on screen about it ? "NTDLL.DLL failed WFP validation" or some such, rather than a spontaneous reboot.

    I'm not so sure on the Dll Proxy idea, I am after all modifications to be built into the DLL itself, my understanding of generating a proxy means that some VERY obvious "JMP 32DISP" instructions will end up in the address space but not be in the on-disk image. This is not good.

    I found the phrack article at again I'd like to point out I know the protection mechanism inspects the LoaderData and LDR_MODULE structures and loads the DLLs off disk manually so again the modifications described I believe would be detectable by the protection. But the article is a good read to fill in some blanks I had before.

    The NTDLL.DLL modifications discussed in this thread are really to free up the debugger use on the target application under WIN32, since I have analyzed the target outside of WIN32 I already know where I can place hardware breakpoints and other such at certain points in time, I already know what the execution path is (i.e. what the target executable is expected it to do next) but I have no way of knowing at this time if that information is executing a decoy. There are a couple of areas where I'd like to compare the real WIN32 environment with debugger against the emulation environment so I can fix the emulation and prove the execution path on both WIN32 and emulator is the same. In order to do that my user-space debugger needs to work.

    From a modification point of view my criteria list of what I am looking to achieve is:
    * No direct EAT hooking to a new location (that is different from the on-disk default indirection jump location)
    * No modification of methods within the first few instructions of the normal function (I do not need to intercept everything only a handful of functions, this means in some cases I have to analyze and write custom interception jump code that understands how to undo any modifications to the stack/registers)
    * No CALLs or JMPs to any code outside of the image address space (certainly not into address space of injected DLLs and such).
    * 100% Working relocation table (relocations positioned over the top of overwritten code need to be quieted).

    I know that the target executable loads DLL image(s) from disk into address space, fixes them up and performs some execution of them, so for all intents and purpose my modifications need to be "real".
    Last edited by Nido; May 22nd, 2009 at 07:46.

  12. #12
    Here we go ok PEB hooking is ok, if you check this code here for kernel32.dll you will get the idea :

    What I do here is to hook kernel32 and advapi32 via PEB and also in fake_k32 hook CreateFileA so when target asks for real kernel32.dll I give it PEB hooked dll from disk, you may do the same here. You don't really need to hook ntdll.dll in whole system, that's not required at all in your scenario. All you have to hook is NtCreateFile and NtOpenFile (or Zw as it's the same in ntdll.dll), and whenever target asks for real ntdll you give it faked version from disk. It's simple as that.
    Last edited by deroko; May 22nd, 2009 at 11:59. Reason: CreateProcess -> CreateFile :) typo

  13. #13
    Quote Originally Posted by deroko View Post
    You don't really need to hook ntdll.dll in whole system, that's not required at all in your scenario.
    Thanks for the example I shall inspect in more detail.

    With regards to "You don't really need to hook ntdll.dll in whole system" yes I do. The protection mechanism opens the NTDLL.DLL file, seeks to the implementation of ZwQueryInfomationProcess() copies 32 bytes directly from the file onto the stack and then executes it.

    So please understand I do need to modify that NTDLL.DLL so those 32bytes now include my intercept code. I've also made the presumption that this code also needs to contain no relocations as I would guess no fixup is done.

    Please remember ring0 is not possible. Once you factor all of these things in the easiest solution is just to patch NTDLL.DLL with a few bytes here and there.

  14. #14
    That's why you hook NtCreateFile and NtOpenFile so when it asks for ntdll.dll on disk you simply redirect to your patched dll.

  15. #15
    |< x != '+' BanMe's Avatar
    Join Date
    Oct 2008
    Farmington NH
    Blog Entries
    to do what deroko rightly suggests from user mode with a dll substitute(proxy is bad word) and PEB hooking..

    hook when process loads(The Ldr routines are good) ..
    Hook LdrpCheckForLoadedDll(or something like that)as well to filter direct handles ntdll and replace them with handles to our image...I think in this fashion we could use the Handle count for the real ntdll, to have exclusive access to it. by checking its reference count...

    Open fake ntdll

    replace TEB.PEB.LDR_DATA.LDR_MODULE_ENTRY for ntdll with your own imagebase and replace all other pointing links(InLoadOrderModuleList,InMemoryOrderModuleList,ect..) to the old ntdll with links to our replacement that can act as a parameter logger or a trampoline of some sort...

    hope this makes sense..

    regards BanMe
    Last edited by BanMe; May 22nd, 2009 at 12:36.

Similar Threads

  1. A Modifying Binaries Tutorial
    By R4ndom in forum Advanced Reversing and Programming
    Replies: 0
    Last Post: August 1st, 2012, 12:54
  2. Modifying an online game
    By selkov in forum Advanced Reversing and Programming
    Replies: 7
    Last Post: September 4th, 2007, 14:12
  3. Modifying the stack
    By 5aLIVE in forum OllyDbg Support Forums
    Replies: 5
    Last Post: July 4th, 2005, 08:37
  4. Modifying SetTimer
    By tonyxxy in forum OllyDbg Support Forums
    Replies: 5
    Last Post: May 16th, 2004, 09:45
  5. Modifying FP Registers
    By anonymous in forum OllyDbg Support Forums
    Replies: 1
    Last Post: June 25th, 2003, 23:08


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts