Created
June 19, 2014 06:55
-
-
Save trietptm/94ad4f6c2eb2804cd50f to your computer and use it in GitHub Desktop.
DetectEmulator http://pastebin.com/D30A12gF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum EmulatorDetections_t | |
{ | |
EmulatorDetections_OS_Beep, | |
EmulatorDetections_OS_GetTickCount, | |
EmulatorDetections_OS_SetLastError, | |
EmulatorDetections_OS_IsBadReadPtr, | |
EmulatorDetections_OS_CreateMutex, | |
EmulatorDetections_OS_IsDebuggerPresent, | |
// EmulatorDetections_OS_FirstModuleHash, | |
EmulatorDetections_CPU_InstructionLength, | |
EmulatorDetections_CPU_DivByZero // , | |
// EmulatorDetections_CPU_PF_ | |
}; | |
bool DetectEmulator(EmulatorDetections_t type) | |
{ | |
switch(type) | |
{ | |
// VBA32 replaces Beep with NOP | |
case EmulatorDetections_OS_Beep: | |
{ | |
SetLastError(ERROR_SUCCESS); | |
Beep(0,0); | |
return GetLastError() != ERROR_INVALID_PARAMETER; | |
} | |
// VMUnpacker returns 0x111 always (!) | |
case EmulatorDetections_OS_GetTickCount: | |
{ | |
return (GetTickCount() == 0x111 && GetTickCount() == 0x111); | |
} | |
// VMUnpacker returns ERROR_ALREADY_EXISTS always (!) | |
case EmulatorDetections_OS_SetLastError: | |
{ | |
SetLastError(ERROR_SUCCESS); | |
return GetLastError() != ERROR_SUCCESS; | |
} | |
// Emulators don't often set up the loaded module list correctly | |
case EmulatorDetections_OS_FirstModuleHash: | |
{ | |
// TODO | |
return 0; | |
} | |
// VMUnpacker returns 0 always (!!) | |
case EmulatorDetections_OS_IsBadReadPtr: | |
{ | |
return IsBadReadPtr(NULL, 1) == 0; | |
} | |
// VMUnpacker returns 1 always, as does VBA32 | |
// although VMUnpacker always returns ERROR_ALREADY_EXISTS, | |
// so we have two detections in one here. | |
case EmulatorDetections_OS_CreateMutex: | |
{ | |
char mutexbuf[16]; | |
int i = rand() % 12 + 3; | |
for(int j = 0; j < i; ++j) mutexbuf[j] = (rand() % 26) + 'A'; | |
mutexbuf[i] = 0; | |
CreateMutexA(NULL, 0, mutexbuf); | |
SetLastError(ERROR_SUCCESS); | |
if(GetLastError() != ERROR_SUCCESS) | |
return 1; | |
CreateMutexA(NULL, 0, mutexbuf); | |
return GetLastError() != ERROR_ALREADY_EXISTS; | |
} | |
// Set the value of Peb->IsBeingDebugged to 1, then call IsDebuggerPresent | |
case EmulatorDetections_OS_IsDebuggerPresent: | |
{ | |
int var1, var2; | |
__asm mov eax, large fs:18h | |
__asm mov eax, [eax+30h] | |
__asm movzx ebx, byte ptr [eax+2] | |
__asm mov var1, ebx | |
__asm mov byte ptr [eax+2], 1 | |
var2 = IsDebuggerPresent(); | |
__asm mov eax, large fs:18h | |
__asm mov eax, [eax+30h] | |
__asm mov ebx, var1 | |
__asm movzx byte ptr [eax+2], bl | |
return !var2; | |
} | |
// VBA32 doesn't check instruction length | |
case EmulatorDetections_CPU_InstructionLength: | |
{ | |
{ | |
bool bDetected = true; | |
__try { | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__emit 66h | |
__asm nop; | |
} | |
__except(1) | |
{ | |
bDetected = false; | |
} | |
return bDetected; | |
} | |
} // end case EmulatorDetections_CPU_InstructionLength | |
// Does your emulator trigger SEH on division by zero? | |
// It ought to :) | |
case EmulatorDetections_CPU_DivByZero: | |
{ | |
{ | |
bool bDetected = true; | |
__try | |
{ | |
__asm mov ebx, 0 | |
__asm cdq | |
__asm div ebx | |
} | |
__except(1) | |
{ | |
bDetected = false; | |
} | |
return bDetected; | |
} | |
} // end case EmulatorDetections_CPU_DivByZero | |
} // end switch | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment