From d03750ae283c51eb6859b95efb2cadbacba68e0c Mon Sep 17 00:00:00 2001 From: Alberto Ortega Date: Thu, 19 Mar 2015 08:28:19 +0100 Subject: [PATCH] Add cpu.c, fix rdtsc detection, add cpuid info, add cpuid hv bit detection --- pafish/Makefile.linux | 5 +++- pafish/Makefile.win | 5 +++- pafish/cpu.c | 59 +++++++++++++++++++++++++++++++++++++++++++ pafish/cpu.h | 11 ++++++++ pafish/main.c | 36 ++++++++++++++++++-------- 5 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 pafish/cpu.c create mode 100644 pafish/cpu.h diff --git a/pafish/Makefile.linux b/pafish/Makefile.linux index 3721229..55f194e 100644 --- a/pafish/Makefile.linux +++ b/pafish/Makefile.linux @@ -4,7 +4,7 @@ LINK = i686-w64-mingw32-gcc WINDRES = i686-w64-mingw32-windres OBJ = Objects/MingW/main.o Objects/MingW/common.o Objects/MingW/utils.o Objects/MingW/debuggers.o Objects/MingW/sandboxie.o \ Objects/MingW/vbox.o Objects/MingW/gensandbox.o Objects/MingW/wine.o Objects/MingW/vmware.o \ - Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/pafish_private.res + Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/cpu.o Objects/MingW/pafish_private.res LINKOBJ = $(OBJ) LIBS = -lwsock32 -liphlpapi -lsetupapi -lmpr -s INCS = @@ -54,5 +54,8 @@ Objects/MingW/qemu.o: $(GLOBALDEPS) qemu.c Objects/MingW/hooks.o: $(GLOBALDEPS) hooks.c $(CC) -c hooks.c -o Objects/MingW/hooks.o $(CFLAGS) +Objects/MingW/cpu.o: $(GLOBALDEPS) cpu.c + $(CC) -c cpu.c -o Objects/MingW/cpu.o $(CFLAGS) + Objects/MingW/pafish_private.res: Objects/MingW/pafish_private.rc $(WINDRES) Objects/MingW/pafish_private.rc --input-format=rc -o Objects/MingW/pafish_private.res -O coff diff --git a/pafish/Makefile.win b/pafish/Makefile.win index 4d72853..1eae8a8 100644 --- a/pafish/Makefile.win +++ b/pafish/Makefile.win @@ -4,7 +4,7 @@ LINK = gcc.exe WINDRES = windres.exe OBJ = Objects/MingW/main.o Objects/MingW/common.o Objects/MingW/utils.o Objects/MingW/debuggers.o Objects/MingW/sandboxie.o \ Objects/MingW/vbox.o Objects/MingW/gensandbox.o Objects/MingW/wine.o Objects/MingW/vmware.o \ - Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/pafish_private.res + Objects/MingW/qemu.o Objects/MingW/hooks.o Objects/MingW/cpu.o Objects/MingW/pafish_private.res LINKOBJ = $(OBJ) LIBS = -L"C:/MinGW32/lib" -lwsock32 -liphlpapi -lsetupapi -lmpr -s INCS = -I"C:/MinGW32/include" @@ -54,5 +54,8 @@ Objects/MingW/qemu.o: $(GLOBALDEPS) qemu.c Objects/MingW/hooks.o: $(GLOBALDEPS) hooks.c $(CC) -c hooks.c -o Objects/MingW/hooks.o $(CFLAGS) +Objects/MingW/cpu.o: $(GLOBALDEPS) cpu.c + $(CC) -c cpu.c -o Objects/MingW/cpu.o $(CFLAGS) + Objects/MingW/pafish_private.res: Objects/MingW/pafish_private.rc $(WINDRES) Objects/MingW/pafish_private.rc --input-format=rc -o Objects/MingW/pafish_private.res -O coff diff --git a/pafish/cpu.c b/pafish/cpu.c new file mode 100644 index 0000000..6a4bfcd --- /dev/null +++ b/pafish/cpu.c @@ -0,0 +1,59 @@ + +#include +#include + +#include "types.h" +#include "cpu.h" + +static inline int rdtsc_diff() { + unsigned long long ret, ret2; + unsigned eax, edx; + + __asm__ volatile("rdtsc" : "=a" (eax), "=d" (edx)); + ret = ((unsigned long long)eax) | (((unsigned long long)edx) << 32); + __asm__ volatile("rdtsc" : "=a" (eax), "=d" (edx)); + ret2 = ((unsigned long long)eax) | (((unsigned long long)edx) << 32); + + return ret2 - ret; +} + +static inline void cpuid_vendor_00(char * vendor) { + int eax, ebx, ecx, edx; + + __asm__ volatile("cpuid" \ + : "=b"(ebx), \ + "=c"(ecx), \ + "=d"(edx) \ + : "a"(0x00)); + sprintf(vendor , "%c%c%c%c", ebx, (ebx >> 8), (ebx >> 16), (ebx >> 24)); + sprintf(vendor+4, "%c%c%c%c", edx, (edx >> 8), (edx >> 16), (edx >> 24)); + sprintf(vendor+8, "%c%c%c%c", ecx, (ecx >> 8), (ecx >> 16), (ecx >> 24)); + vendor[12] = 0x00; +} + +static inline int cpuid_hv_bit() { + int ecx; + __asm__ volatile("cpuid" \ + : "=c"(ecx) \ + : "a"(0x01)); + return (ecx >> 31) & 0x1; +} + +int cpu_rdtsc() { + int i, avg = 0, diff; + for (i = 0; i < 10; i++) { + diff = rdtsc_diff(); + avg = avg + diff; + Sleep(500); + } + return (avg / 10) > 750 ? TRUE : FALSE; +} + +int cpu_hv() { + return cpuid_hv_bit() ? TRUE : FALSE; +} + +void cpu_write_vendor(char * vendor) { + cpuid_vendor_00(vendor); +} + diff --git a/pafish/cpu.h b/pafish/cpu.h new file mode 100644 index 0000000..55d5b75 --- /dev/null +++ b/pafish/cpu.h @@ -0,0 +1,11 @@ + +#ifndef CPU_H +#define CPU_H + +int cpu_rdtsc(); + +int cpu_hv(); + +void cpu_write_vendor(char *); + +#endif diff --git a/pafish/main.c b/pafish/main.c index c012051..27dd568 100644 --- a/pafish/main.c +++ b/pafish/main.c @@ -15,6 +15,7 @@ #include "wine.h" #include "vmware.h" #include "qemu.h" +#include "cpu.h" /* Pafish (Paranoid fish) @@ -35,6 +36,7 @@ int main(int argc, char *argv[]) { char icon[] = "Blue fish icon thanks to http://www.fasticon.com/", winverstr[32], aux[1024]; + char cpu_vendor[13]; OSVERSIONINFO winver; unsigned short original_colors = 0; @@ -48,11 +50,15 @@ int main(int argc, char *argv[]) snprintf(winverstr, sizeof(winverstr)-sizeof(winverstr[0]), "%d.%d build %d", winver.dwMajorVersion, winver.dwMinorVersion, winver.dwBuildNumber); + /* Get CPU vendor */ + cpu_write_vendor(cpu_vendor); + printf("[*] Windows version: %s\n", winverstr); + printf("[*] CPU vendor: %s\n", cpu_vendor); snprintf(aux, sizeof(aux)-sizeof(aux[0]), "Windows version: %s", winverstr); write_log(aux); - - printf("[*] Running checks ...\n"); + snprintf(aux, sizeof(aux)-sizeof(aux[0]), "CPU vendor: %s", cpu_vendor); + write_log(aux); /* Debuggers detection tricks */ printf("\n[-] Debuggers detection\n"); @@ -75,6 +81,24 @@ int main(int argc, char *argv[]) else print_not_traced(); } + /* CPU information based detection tricks */ + printf("\n[-] CPU information detection\n"); + printf("[*] Checking the difference between CPU timestamp counters (rdtsc) ... "); + if (cpu_rdtsc() == TRUE) { + print_traced(); + write_log("CPU VM traced by checking the difference between CPU timestamp counters (rdtsc)"); + write_trace("hi_CPU_VM_rdtsc"); + } + else print_not_traced(); + + printf("[*] Checking hypervisor bit in cpuid feature bits ... "); + if (cpu_hv() == TRUE) { + print_traced(); + write_log("CPU VM traced by checking hypervisor bit in cpuid feature bits"); + write_trace("hi_CPU_VM_hypervisor_bit"); + } + else print_not_traced(); + /* Generic sandbox detection tricks */ printf("\n[-] Generic sandbox detection\n"); printf("[*] Using mouse activity ... "); @@ -133,14 +157,6 @@ int main(int argc, char *argv[]) } else print_not_traced(); - printf("[*] Checking the difference between CPU timestamp counters (rdtsc) ... "); - if (gensandbox_rdtsc() == TRUE) { - print_traced(); - write_log("Sandbox traced by checking the difference between CPU timestamp counters (rdtsc)"); - write_trace("hi_sandbox_rdtsc"); - } - else print_not_traced(); - /* Hooks detection tricks */ printf("\n[-] Hooks detection\n"); printf("[*] Checking function DeleteFileW method 1 ... ");