https://github.com/capesandbox/capemon-hook-generator
CAPEv2 (capemon) hook skeleton generator (hookdefs) for your malware analysis needs.
https://github.com/capesandbox/capemon-hook-generator
api apihook apihooking cape capesandbox capev2 hook hooking hooks malware malware-analysis malware-detection malware-research malware-samples sandbox windows windowsapi
Last synced: 5 months ago
JSON representation
CAPEv2 (capemon) hook skeleton generator (hookdefs) for your malware analysis needs.
- Host: GitHub
- URL: https://github.com/capesandbox/capemon-hook-generator
- Owner: CAPESandbox
- License: gpl-3.0
- Created: 2023-01-03T16:17:42.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-12-16T12:25:13.000Z (over 1 year ago)
- Last Synced: 2025-09-04T20:50:29.530Z (10 months ago)
- Topics: api, apihook, apihooking, cape, capesandbox, capev2, hook, hooking, hooks, malware, malware-analysis, malware-detection, malware-research, malware-samples, sandbox, windows, windowsapi
- Language: Python
- Homepage:
- Size: 3.83 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Citation: CITATION.cff
- Authors: AUTHORS
Awesome Lists containing this project
README
# CAPEv2 (capemon) hook(s) generator
This script automatically generates new hooks (hookdefs) for capemon, the CAPEv2 monitor. The hooks are generated according to the info specified in [this repo](https://github.com/reverseame/capemon?tab=readme-ov-file#how-to-add-hooks-to-capemon) (now included in the official [CAPE](https://github.com/kevoreilly/capemon?tab=readme-ov-file#how-to-add-hooks-to-capemon) repo). Please bear in mind the generated files are just skeletons to help you define new hooks, you must adapt them according to your needs.
## Usage
The script requires close to zero configuration. If you want it to Google for the APIs not present in the downloaded `winapi_categories.json` file, just specify your Google API and Google CSE keys in the `config.ini` file.
Run `python3 generate_hooks.py -h` to print more information.
## How does it work?
The script performs the following steps:
1. Check if API kes have been specified in `config.ini` to determine whether Google search is enabled.
2. Checks whether [`winapi_categories.json`](https://github.com/reverseame/winapi-categories) file is present in the current directory. If it isn't, the script downloads it.
3. Checks whether the original [`hooks.c`](https://github.com/kevoreilly/capemon) file is present in the current directory. If it isn't, the script downloads it.
4. Parses `hooks.c` to get the APIs already hooked by CAPEv2.
5. Creates the skeleton files extended_hooks.c, extended_hooks.h and extended_hook_misc.c.
6. If `--dll` is specified, parse each path, extract its EAT and jump to step 8.
7. If `--api` is specified, parse each API call.
8. For every API call, check if it is already present in `hooks.c`. If it isn't try to generate its hook skeleton.
9. Look if the API call is present in `winapi_categories.json`. If it is, read its data, write the files and go back to 8 with the next API call.
10. If the Google search is enabled, Google for it in `site:learn.microsoft.com`. Scrape the first result (we assume it is the correct one), parse the data and go back to 8 with the next API call. If there are no Google results, go back to 8 with the next API call.
## Example
Let's say you already configured your keys in the `config.ini` file (so the script uses Google to scrape learn.microsoft.com for the entries not present in the JSON file) and you want to generate capemon hooks skeleton for the following APIs: CloseHandle, Process32First, Process32Next, ExitProcess, GetProcAddress, GetModuleHandleA, GetModuleHandleW, Sleep, CreateMutexA, CreateMutexW, GetVolumeInformationA and GetVolumeInformationW. You would run the script like so:
```
python3 generate_hooks.py --api CloseHandle,Process32First,Process32Next,ExitProcess,GetProcAddress,GetModuleHandleA,GetModuleHandleW,Sleep,CreateMutexA,CreateMutexW,GetVolumeInformationA,GetVolumeInformationW
```
The script produces three files. Namely, extended_hooks.c, extended_hooks.h and extended_hook_misc.c with the following contents
### extended_hooks.c example
```c
/*
File autogenerated by capemon hook generator (https://github.com/RazviOverflow/cape-hook-generator)
The contents of this file can be appended to any array present in your local hooks.c.
For example, hook_t full_hooks[].
*/
HOOK(kernel32, CloseHandle),
HOOK(kernel32, Process32First),
HOOK(kernel32, Process32Next),
HOOK(kernel32, ExitProcess),
HOOK(kernel32, GetProcAddress),
HOOK(kernel32, GetModuleHandleA),
HOOK(kernel32, GetModuleHandleW),
HOOK(kernel32, Sleep),
HOOK(kernel32, CreateMutexA),
HOOK(kernel32, CreateMutexW),
HOOK(kernel32, GetVolumeInformationA),
HOOK(kernel32, GetVolumeInformationW),
```
### extended_hooks.h example
```c
/*
File autogenerated by capemon hook generator (https://github.com/RazviOverflow/cape-hook-generator)
The contents of this file can be appended to your local hooks.h
WINAPI calling convention is assumed, but it might be incorrect!
*/
HOOKDEF(BOOL, WINAPI, CloseHandle,
_In_ HANDLE hObject
);
HOOKDEF(BOOL, WINAPI, Process32First,
_In_ HANDLE hSnapshot,
_Inout_ LPPROCESSENTRY32 lppe
);
HOOKDEF(BOOL, WINAPI, Process32Next,
_In_ HANDLE hSnapshot,
_Out_ LPPROCESSENTRY32 lppe
);
HOOKDEF(VOID, WINAPI, ExitProcess,
_In_ UINT uExitCode
);
HOOKDEF(FARPROC, WINAPI, GetProcAddress,
_In_ HMODULE hModule,
_In_ LPCSTR lpProcName
);
HOOKDEF(HMODULE, WINAPI, GetModuleHandleA,
_In_opt_ LPCSTR lpModuleName
);
HOOKDEF(HMODULE, WINAPI, GetModuleHandleW,
_In_opt_ LPCWSTR lpModuleName
);
HOOKDEF(VOID, WINAPI, Sleep,
_In_ DWORD dwMilliseconds
);
HOOKDEF(HANDLE, WINAPI, CreateMutexA,
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCSTR lpName
);
HOOKDEF(HANDLE, WINAPI, CreateMutexW,
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCWSTR lpName
);
HOOKDEF(BOOL, WINAPI, GetVolumeInformationA,
_In_opt_ LPCSTR lpRootPathName,
_Out_opt_ LPSTR lpVolumeNameBuffer,
_In_ DWORD nVolumeNameSize,
_Out_opt_ LPDWORD lpVolumeSerialNumber,
_Out_opt_ LPDWORD lpMaximumComponentLength,
_Out_opt_ LPDWORD lpFileSystemFlags,
_Out_opt_ LPSTR lpFileSystemNameBuffer,
_In_ DWORD nFileSystemNameSize
);
HOOKDEF(BOOL, WINAPI, GetVolumeInformationW,
_In_opt_ LPCWSTR lpRootPathName,
_Out_opt_ LPWSTR lpVolumeNameBuffer,
_In_ DWORD nVolumeNameSize,
_Out_opt_ LPDWORD lpVolumeSerialNumber,
_Out_opt_ LPDWORD lpMaximumComponentLength,
_Out_opt_ LPDWORD lpFileSystemFlags,
_Out_opt_ LPWSTR lpFileSystemNameBuffer,
_In_ DWORD nFileSystemNameSize
);
```
### extended_hook_misc.c example
```c
/*
File autogenerated by capemon hook generator (https://github.com/RazviOverflow/cape-hook-generator)
The contents of this file can be appended to your local hook_{{category}}.c they belong.
WINAPI calling convention is assumed, but it might be incorrect!
*/
HOOKDEF(BOOL, WINAPI, CloseHandle,
_In_ HANDLE hObject
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked CloseHandle\n");
BOOL ret = Old_CloseHandle(hObject);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(BOOL, WINAPI, Process32First,
_In_ HANDLE hSnapshot,
_Inout_ LPPROCESSENTRY32 lppe
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked Process32First\n");
BOOL ret = Old_Process32First(hSnapshot,lppe);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(BOOL, WINAPI, Process32Next,
_In_ HANDLE hSnapshot,
_Out_ LPPROCESSENTRY32 lppe
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked Process32Next\n");
BOOL ret = Old_Process32Next(hSnapshot,lppe);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(VOID, WINAPI, ExitProcess,
_In_ UINT uExitCode
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked ExitProcess\n");
Old_ExitProcess(uExitCode);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
}
HOOKDEF(FARPROC, WINAPI, GetProcAddress,
_In_ HMODULE hModule,
_In_ LPCSTR lpProcName
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked GetProcAddress\n");
FARPROC ret = Old_GetProcAddress(hModule,lpProcName);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(HMODULE, WINAPI, GetModuleHandleA,
_In_opt_ LPCSTR lpModuleName
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked GetModuleHandleA\n");
HMODULE ret = Old_GetModuleHandleA(lpModuleName);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(HMODULE, WINAPI, GetModuleHandleW,
_In_opt_ LPCWSTR lpModuleName
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked GetModuleHandleW\n");
HMODULE ret = Old_GetModuleHandleW(lpModuleName);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(VOID, WINAPI, Sleep,
_In_ DWORD dwMilliseconds
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked Sleep\n");
Old_Sleep(dwMilliseconds);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
}
HOOKDEF(HANDLE, WINAPI, CreateMutexA,
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCSTR lpName
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked CreateMutexA\n");
HANDLE ret = Old_CreateMutexA(lpMutexAttributes,bInitialOwner,lpName);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(HANDLE, WINAPI, CreateMutexW,
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCWSTR lpName
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked CreateMutexW\n");
HANDLE ret = Old_CreateMutexW(lpMutexAttributes,bInitialOwner,lpName);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(BOOL, WINAPI, GetVolumeInformationA,
_In_opt_ LPCSTR lpRootPathName,
_Out_opt_ LPSTR lpVolumeNameBuffer,
_In_ DWORD nVolumeNameSize,
_Out_opt_ LPDWORD lpVolumeSerialNumber,
_Out_opt_ LPDWORD lpMaximumComponentLength,
_Out_opt_ LPDWORD lpFileSystemFlags,
_Out_opt_ LPSTR lpFileSystemNameBuffer,
_In_ DWORD nFileSystemNameSize
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked GetVolumeInformationA\n");
BOOL ret = Old_GetVolumeInformationA(lpRootPathName,lpVolumeNameBuffer,nVolumeNameSize,lpVolumeSerialNumber,lpMaximumComponentLength,lpFileSystemFlags,lpFileSystemNameBuffer,nFileSystemNameSize);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
HOOKDEF(BOOL, WINAPI, GetVolumeInformationW,
_In_opt_ LPCWSTR lpRootPathName,
_Out_opt_ LPWSTR lpVolumeNameBuffer,
_In_ DWORD nVolumeNameSize,
_Out_opt_ LPDWORD lpVolumeSerialNumber,
_Out_opt_ LPDWORD lpMaximumComponentLength,
_Out_opt_ LPDWORD lpFileSystemFlags,
_Out_opt_ LPWSTR lpFileSystemNameBuffer,
_In_ DWORD nFileSystemNameSize
){
DebuggerOutput("[***** DEBUG MESSAGE - EXTENDED HOOKS *****] Hooked GetVolumeInformationW\n");
BOOL ret = Old_GetVolumeInformationW(lpRootPathName,lpVolumeNameBuffer,nVolumeNameSize,lpVolumeSerialNumber,lpMaximumComponentLength,lpFileSystemFlags,lpFileSystemNameBuffer,nFileSystemNameSize);
LOQ_bool("misc", ""); // Modify category, LOQ_ function and log message according to your needs
return ret;
}
```
## Limitations
The script requires internet connection to be able to download both `winapi_categories.json` and `hooks.c` files, and also to use Google (in case it is configured).
Another limiation is the quota / search rate imposed by Google. As of right now, Google CSE (Custom Search Engine) API limits the automation to 100 searches per day.
**WINAPI** calling convention is assumed. Modify autogenerated files as needed.
## Acknowledgments
Thanks to [Kevin O'Reilly](https://github.com/kevoreilly) and [Andriy Brukhovetskyy (a.k.a doomedraven)](https://github.com/doomedraven).
## Comments
- Changes to `config.ini` are ommited with `git update-index --skip-worktree config.ini`.