Gaddar is a x64 Windows Malware Development Library written in C and Assembly from scratch. It has its own hash and encryption libraries, custom std library which includes some of std C functions rewritten in Assembly from scratch and metasploit like Block Loaders.
Gaddar means rough, ruthless, cruel in English. The name comes from an Erkin Koray song which I love a lot.
Gaddar is written using MSVS2022, so using MSVS2022 is recommended. After cloning to the repo into your local machine, you can start using it by either creating a main.c into the Gaddar's solution or copying the header and source files to your own solution. It's up to you!
For now the hash library has 2 mods which are written by Muzaffer Umut Şahin and Mert Döner. To switch modes edit funcs.h and change CURRENT_HASH_MODE macro with the hash mode macro you wish to have. Additionally, you can change Hash's source. Both hashes are written in C and Assembly. The default value for CURRENT_HASH_MODE is HASH_MODE_A and the default value for CURRENT_SOURCE is USE_ASSEMBLY_SOURCE
#include "hash.h"
int main(){
HashContext* ctx = NULL;
DWORD hashA = 0;
DWORD hashW = 0;
if (!InitHashContext()) {
return -1;
}
ctx = GetHashContext();
if (ctx == NULL){
return -2;
}
hashA = ctx->HashA("ntdll.dll");
hashW = ctx->HashW(L"my dear string");
DestroyHashContext();
return 0;
}For now, encryption library supports RC4 and XCHACHA20 encryptions. To change the encryption modes, change the CURRENT_ENCRYPTION_MODE macro from encryption.h with one of RC4 or XCHACHA20
Check #5
#include "encryption.h"
int main(){
EncryptionContext* ctx = NULL;
unsigned char buf[] = "hello mate!";
unsigned char key[] = "keygenme123456";
if(!InitEncryptionContext()) {
return -1;
}
ctx = GetEncryptionContext();
if(ctx == NULL){
return -2;
}
if(!ctx->Encrypt(buf,key,sizeof(key)-1)){
return -3;
}
if(!ctx->Decrypt(buf,key,sizeof(key)-1)){
return -4;
}
DestroyEncryptionContext();
return 0;
}Yeah, we have a pseudo random key generator which uses a custom implementation of GetTickCount64.
#include "encryption.h"
#define KEYSIZE 256
int main(){
HANDLE hHeap = gGetProcessHeap();
unsigned char* randomKey = (unsigned char*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,KEYSIZE);
if (randomKey == NULL){
return -1;
}
RandomKeyGeneratorViaGetTickCount64(randomKey,KEYSIZE);
// if you wish you can print out the variable
HeapFree(hHeap,0,randomKey);
return 0;
}Gaddar has x64 NtBlockLoader and BlockLoader. These Block Loaders can be used to dynamically resolve addresses of functions from various DLLs loaded to the process.
Block Loader can find any function from any loaded DLL to the current process.
#include "block_loader.h"
int main(){
LPVOID pVirtualAlloc = BlockLoader(0x6d6a) // HashCtx->HashW(L"kernel32.dll") + HashCtx->HashA("VirtualAlloc")
return 0; // if you wish you can call it, since it is a function pointer
}#include "block_loader.h"
int main(){
DWORD dwSyscallNumber = 0;
DWORD dwHash = 0x3ff6; // ctx->HashA("NtCreateThreadEx");
HANDLE hHandle = NULL;
NTSTATUS ret = -1;
LPVOID pNtCreateThreadEx = NtBlockLoader(dwHash,&dwSyscallNumber);
void* pArgs[] = {&hHandle,THREAD_ALL_ACCESS,NULL,gGetCurrentProcess(),func,NULL,0x1 ,0,0,0,NULL};
if(pNtCreateThreadEx == NULL || !dwSyscallNumber) {
return -1;
}
ret = ArraySyscall(pNtCreateThreadEx,dwSyscallNumber,11,pArgs);
if(ret != STATUS_SUCCESS) {
return -1;
}
return 0;
}You can use the existing functions to write your own Assembly stubs with MASM. You can check my own stubs to get the idea. I will write more comprehensive docs later.
We don't have strict code style rules. However, try to follow the existing code style of the codebase. You don't need to worry about it a lot, I will adjust your PR as soon as you open it :D!
The only rule you need to follow is NO AI I won't merge any PRs written by AI.
-
Muzaffer Umut ŞAHİN mailatmayinlutfen@gmail.com
-
Mert Döner mertdoner09@gmail.com