MiVerifyImageHeader


  • administrators

    Does anyone know which kernel module contains this function?

    I’m seeing it being used inside NtCreateSection but I can’t find it in IDA Pro in ntoskrnl.exe or ntdll.dll . In fact, Mi symbols in general seem to be missing in those files. I’m seeing plenty of Mm symbols though.



  • The file you linked already contains source code for this function.
    https://github.com/markjandrews/wrk-v1.2/blob/master/base/ntos/mm/creasect.c#L3909

    But anyway:

    0:000> x ntoskrnl!MiVerifyImageHeader
    00000001`4043e84c ntoskrnl!MiVerifyImageHeader (void)
    

    0_1507039183605_dfg.PNG


  • administrators

    @dfsgyusduyfg awesome, good find! That was a fun project. Sorry for late reply, gonna be more active on here now.



  • The Nt*/Zw* routines exported by NTDLL aren’t the real routines, they are just user-mode wrapper routines which will perform a user-mode to kernel-mode transition via a system call.

    MiVerifyImageHeader (NTOSKRNL) is called by MiCreateImageFileMap (NTOSKRNL). MiCreateImageFileMap is called by MiCreateNewSection and this routine is called by MiCreateImageOrDataSection, which is called by MiCreateSection… Which happens to be invoked by MmCreateSection. For the record, NtCreateSection calls MmCreateSection.

    You cannot invoke any of these routines from user-mode, but you can call NtCreateSection/ZwCreateSection (NTDLL - Nt*/Zw* have the same address in user-mode) in user-mode which will cause NtCreateSection (NTOSKRNL) to be called by the Windows Kernel once the system call operation is handled. Even from kernel-mode where those Mm* and Mi* routines are present in the address space of NTOSKRNL, you cannot simply just call the ones listed because they are not exported - the exception for the routines listed above is MmCreateSection which does happen to be exported by NTOSKRNL.

    If you need to call non-exported kernel-only routines then you would have to locate the address somehow. You’ll need to use memory scanning techniques which will require you to make a signature - if the target address is exposed due to a reference then you can extract it from there as well.



  • Hey when you say “make a signature” do you usually use a raw byte sig or a hash?
    @ntopcode said in MiVerifyImageHeader:

    The Nt*/Zw* routines exported by NTDLL aren’t the real routines, they are just user-mode wrapper routines which will perform a user-mode to kernel-mode transition via a system call.

    MiVerifyImageHeader (NTOSKRNL) is called by MiCreateImageFileMap (NTOSKRNL). MiCreateImageFileMap is called by MiCreateNewSection and this routine is called by MiCreateImageOrDataSection, which is called by MiCreateSection… Which happens to be invoked by MmCreateSection. For the record, NtCreateSection calls MmCreateSection.

    You cannot invoke any of these routines from user-mode, but you can call NtCreateSection/ZwCreateSection (NTDLL - Nt*/Zw* have the same address in user-mode) in user-mode which will cause NtCreateSection (NTOSKRNL) to be called by the Windows Kernel once the system call operation is handled. Even from kernel-mode where those Mm* and Mi* routines are present in the address space of NTOSKRNL, you cannot simply just call the ones listed because they are not exported - the exception for the routines listed above is MmCreateSection which does happen to be exported by NTOSKRNL.

    If you need to call non-exported kernel-only routines then you would have to locate the address somehow. You’ll need to use memory scanning techniques which will require you to make a signature - if the target address is exposed due to a reference then you can extract it from there as well.



  • @master I’m referring to raw bytes, and wild-cards can be very helpful as well. However this does count as a signature.

    For example, if we had a stub which started with MOV R10, RCX then the bytes for this would be 0x4C, 0x8B, 0xD1. Now if we wanted to locate the first stub within a specific module which made use of MOV R10, RCX then we could find the base address of the target module in-memory and then calculate the base address of the next module in-memory (so we know where to stop scanning). Then we could scan between that memory range until we get a hit on the signature we have which consists of 0x4C, 0x8B, 0xD1. You could always format it differently though depending on your scanning engine.

    Now when it comes down to signature scanning, wild-cards can be very helpful. It allows you to put a wild-card (e.g. “??”) in a location of the byte signature in which the byte/s where the wild-card/s are located may change in the future, to improve reliability of the signature. This allows you to scan for XXXX??XXXXXX in which the byte where ?? is will be ignored.



  • @ntopcode oh i like it, so basically like a FLIRT signature?

    You would just write some code to scan the address space for those bytes and work from there…

    good info thanx


Log in to reply
 

Looks like your connection to Malware Analysis Forums was lost, please wait while we try to reconnect.