Closed oalieno closed 8 months ago
Hi - this is good observation and an interesting question... I found the commit in spender/cuckoomon_modified where this implementation first appears: https://github.com/spender-sandbox/cuckoomon-modified/commit/faf6210460dda60a065dc590e5cde509881487a8
I like your idea of moving the logging to the alt part - is this working well? Can you PR?
Now we will treat it as a notail hook, which unfortunately means we'll have no insight into the return value of the call.
In the commit faf6210 you provided, it sounds like the ordering of LdrLoadDll
call is intentional? But I can't understand the reason for that. I still trying to figure out the whole hooking logic for LdrLoadDll
.
For the idea of moving the logging to HOOKDEF_ALT
function. I have tried this solution, but it will miss some of the calls. This happens because in HOOKDEF_NOTAIL
, if ret
is 0, it won't go into the HOOKDEF_ALT
function and go directly back to the original LdrLoadDLL
.
I too am still trying to understand the logic - thanks for looking into it. I am interested in which cases return ret
as 0 from the HOOKDEF_NOTAIL
- can you give some examples? I am trying to understand what reason there might be for intentionally returning 0 and avoiding the HOOKDEF_ALT
code.
For example, loading a notexist.dll
will result in ret = 0
. It will walk into L86-L93 block and then not set the ret = 1
because the result of GetFileAttributesW
is INVALID_FILE_ATTRIBUTES
.
What do you mean by notexist.dll
- an attempt to load a file that does not exist? Of course I can read the code, I am curious in what real world scenario this occurs. It would seem that attempting to load a file that does not exist would produce a failure from the call to the real LdrLoadDll
which could be used to decide whether to log or not.
Sorry for the misunderstanding. Here's my understanding so far:
In HOOKDEF_NOTAIL
, return 0 -> jmp LdrLoadDll
, return 1 -> jmp HOOKDEF_NOTAIL
.
HOOKDEF_NOTAIL
is only a wrapper for LdrLoadDll
to save the hook_info
. But, I don't understand what is hook_info
and why does return 1 need to save this hook_info
.
Here is some additional information regarding my original line of thought in identifying this issue:
Initially, I was looking for a way to determine if the library load success or not. Because I have seen many cases recently that malwares use legitimate software to sideload their malicious dll. I want to test if an exe dynamically load a not existed dll, which can potentially be used for dll sideloading. Therefore, I looked into the LdrLoadDll
API call and found that whether the call succeed or not, it always return 0 (STATUS_SUCCESS) and the BaseAddress
is always 0 too. There is no way to tell if the call succeed or not from the report.
I may have to just perform some experiments to see if this logic can be improved by trial and error...
Thanks for bringing this issue to my attention.
I notice that the value of
BaseAddress
in theLdrLoadDll
is always null. Because we call theLOQ_ntstatus
to log the api before we callOld_LdrLoadDll
. And theModuleHandle
is an out parameter which is set after the function call. I am wondering why the original implementation is designed this way and if it is intentional.https://github.com/kevoreilly/capemon/blob/9b7258bdff80cbd302ca340834f61cb1bfff1f10/hook_special.c#L74-L79
In addition, I attempted to move the logging to the
HOOKDEF_ALT
ofLdrLoadDll
after the function call. It can correctly display theBaseAddress
of the loaded DLL. But some of the DLL, which is nonexist dll, will not enter thisHOOKDEF_ALT
ofLdrLoadDll
.