Process Debugging

Badger has support for various debugging features. The current debugging features are limited to identification, however this allows the possibility of future releases to have the capability of CPU instruction modifications. This was added in order to identify and target specific EDRs and monitor if the API calls are hooked.

Loaded Module Enumeration

The list_modules command lists the loaded DLLs in the current process or a target process. This helps not only to identify EDR DLLs, but also other important DLLs such as clr.dll for fork&run. It takes a PID as an optional argument to list the DLLs loaded in a target process.

Module Export Enumeration

The list_exports command can be used to list all the exports of a DLL loaded in the current process. This can be useful to identify if a DLL loaded by an EDR has any specific exports that you might want to modify/patch. The current release only supports identification of the exports. However, a BOF should be good enough to perform the job of export address patching for now.

Memory hunting

The memhunt command was added to identify the RX/RWX regions across the current process or a target process. It takes a process ID and a PAGE permission in hex to identify and hunt for memory regions and return the addresses. Further releases will include a feature to free up allocated regions of memory which can be a Private Commit, Image Commit or even SEC Commits. According to Microsoft documentation, the PAGE_EXECUTE_READWRITE stands for 0x40 in hex.

#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
#define PAGE_WRITECOPY 0x08
#define PAGE_EXECUTE 0x10
#define PAGE_EXECUTE_READ 0x20
#define PAGE_GUARD 0x100
#define SEC_LARGE_PAGES 0x80000000

So, in order to search for this page type, we can provide the argument ‘40’ to the memhunt command to search for RWX regions. I executed InternalMonologue.exe using sharpinline in the below figure, which creates several RWX regions for the mscoree.dll and mscorlib.dll. These RWX regions can be found using the memhunt command. Badger itself does not have any RWX regions by default unless created by the operator.

Detecting Userland Hooks

Badger comes prebuilt with a miniature debugger written in Assembly since v0.9 release. The detect command, released in v1.0, uses this feature to hunt down all hooks in a given DLL, similar to what it does when it tries to find the hooked Syscalls. This feature is not limited to just finding the hooks on an API call. It will enumerate the whole memory region recursively, follow any short or long jumps (Qword Ptrs) and any address stored in the registers or data segments [ds:] to hunt jump(short or long), call, pop and ret instructions. It will do this till it eventually finds the final region and entrypoint of the hooked instruction in the target DLL. Below is a quick example of Crowdstrike’s userland DLL ‘umppc14406.dll’ which hooks several Syscalls and NTAPI calls in ntdll.dll.