Find DLL exports #7
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello again 😄
With this PR, we find the export address of all DLL functions ourselves, so we no longer rely on
GetProcAddressandLdrGetProcedureAddress. The idea is to stay away from Kernel32 and NTDLL as much as possible. Resolving several functions might lead to detectionI have tried to resolve all exports of Kernel32, NTDLL, User32. vcruntime40 and stdlib and it worked very well, so I am confident the implementation is solid.
One interesting thing I found while developing this:
For some weird reason, Kernel32 (and a few others) exports some functions that aren't really defined in Kernel32, but in other libraries (maybe everybody knew this but me?)
When you try to resolve those functions, you get a pointer to a string that describes where that function is truly defined.
For example, AcquireSRWLockExclusive is a function exported by Kernel32, that resolves to an address that has this string:
NTDLL.RtlAcquireSRWLockExclusive, meaning the function is defined in ntdll as RtlAcquireSRWLockExclusive.So that is why the function is recursive, it needs to handle those cases. (luckily your test DLL loads one of these "fake" exports, so I was able to find this behavior)
Anyway, hope you find it useful
Edit:
I have also found that in some weird cases, libraries such as Kernel32 does this thing where a function "points" to another library and function name, but the library is like deprecated and the function is in truth implemented in Kernel32.
That is why if the resolve fails, it tries with Kernel32 and KernelBase. You can try to resolve all exports of the DLL you like and compare the result with what
LdrGetProcedureAddresssays it is and confirm that it works for all cases.Let me know if this is unclear and you want to clarify something.