From edc56b1c98beac5f19a273695f66b8bc58722938 Mon Sep 17 00:00:00 2001 From: manuel Date: Sat, 9 Mar 2013 15:28:20 +0100 Subject: add signature scanner --- sigscan.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 sigscan.cpp (limited to 'sigscan.cpp') diff --git a/sigscan.cpp b/sigscan.cpp new file mode 100644 index 0000000..f8ab0e3 --- /dev/null +++ b/sigscan.cpp @@ -0,0 +1,124 @@ +#include +#include "sigscan.h" + +/* There is no ANSI ustrncpy */ +unsigned char* ustrncpy(unsigned char *dest, const unsigned char *src, int len) { + while(len--) + dest[len] = src[len]; + + return dest; +} + +/* ////////////////////////////////////// + CSigScan Class + ////////////////////////////////////// */ +unsigned char* CSigScan::base_addr; +size_t CSigScan::base_len; +void *(*CSigScan::sigscan_dllfunc)(const char *pName, int *pReturnCode); + +/* Initialize the Signature Object */ +int CSigScan::Init(const unsigned char *sig, const char *mask, size_t len) { + is_set = 0; + + sig_len = len; + + if ( sig_str ) + delete[] sig_str; + + sig_str = new unsigned char[sig_len]; + ustrncpy(sig_str, sig, sig_len); + + if ( sig_mask ) + delete[] sig_mask; + + sig_mask = new char[sig_len/*+1*/]; + strncpy(sig_mask, mask, sig_len); + //sig_mask[sig_len+1] = 0; + + if(!base_addr) + return 2; // GetDllMemInfo() Failed + + if((sig_addr = FindSignature()) == NULL) + return 1; // FindSignature() Failed + + is_set = 1; + // SigScan Successful! + + return 0; +} + +/* Destructor frees sig-string allocated memory */ +CSigScan::~CSigScan(void) { + delete[] sig_str; + delete[] sig_mask; +} + +/* Get base address of the server module (base_addr) and get its ending offset (base_len) */ +bool CSigScan::GetDllMemInfo(void) { + void *pAddr = (void*)sigscan_dllfunc; + base_addr = 0; + base_len = 0; + + #ifdef WIN32 + MEMORY_BASIC_INFORMATION mem; + + if(!pAddr) + return false; // GetDllMemInfo failed!pAddr + + if(!VirtualQuery(pAddr, &mem, sizeof(mem))) + return false; + + base_addr = (unsigned char*)mem.AllocationBase; + + IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER*)mem.AllocationBase; + IMAGE_NT_HEADERS *pe = (IMAGE_NT_HEADERS*)((unsigned long)dos+(unsigned long)dos->e_lfanew); + + if(pe->Signature != IMAGE_NT_SIGNATURE) { + base_addr = 0; + return false; // GetDllMemInfo failedpe points to a bad location + } + + base_len = (size_t)pe->OptionalHeader.SizeOfImage; + + #else + + Dl_info info; + struct stat buf; + + if(!dladdr(pAddr, &info)) + return false; + + if(!info.dli_fbase || !info.dli_fname) + return false; + + if(stat(info.dli_fname, &buf) != 0) + return false; + + base_addr = (unsigned char*)info.dli_fbase; + base_len = buf.st_size; + #endif + + return true; +} + +/* Scan for the signature in memory then return the starting position's address */ +void* CSigScan::FindSignature(void) { + unsigned char *pBasePtr = base_addr; + unsigned char *pEndPtr = base_addr+base_len; + size_t i; + + while(pBasePtr < pEndPtr) { + for(i = 0;i < sig_len;i++) { + if((sig_mask[i] != '?') && (sig_str[i] != pBasePtr[i])) + break; + } + + // If 'i' reached the end, we know we have a match! + if(i == sig_len) + return (void*)pBasePtr; + + pBasePtr++; + } + + return NULL; +} -- cgit v1.2.3