My favorites | Sign in
Project Logo
          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "helper.h"

using std::cout;
using std::endl;
using std::hex;


HMODULE hKernel32 = GetModuleHandle("kernel32.dll");

/*
* 7C810659 > 33ED XOR EBP, EBP
* 7C81065B 53 PUSH EBX
* 7C81065C 50 PUSH EAX
* 7C81065D 6A 00 PUSH 0
* 7C81065F ^ E9 E8AFFFFF JMP 7C80B64C ; kernel32.BaseThreadStart
*/
LPSTR pSig = "\x33\xED\x53\x50\x6A\xE9";
DWORD BaseThreadStartThunk = FindCode(pSig, sizeof(pSig), GetTextAddress(hKernel32), GetTextSize(hKernel32));
DWORD BaseThreadStartThunk_Jmp = (BaseThreadStartThunk + 0x6);
DWORD BaseThreadStart = (BaseThreadStartThunk_Jmp + (int)*(DWORD*)(BaseThreadStartThunk_Jmp + 1) + 5);


bool IsSuspiciousAddress(DWORD dwAddress)
{
static DWORD lpLoadLibraryA = (DWORD)GetProcAddress(hKernel32, "LoadLibraryA");
static DWORD lpLoadLibraryW = (DWORD)GetProcAddress(hKernel32, "LoadLibraryW");
static DWORD lpExitProcess = (DWORD)GetProcAddress(hKernel32, "ExitProcess");
static DWORD lpFreeLibrary = (DWORD)GetProcAddress(hKernel32, "FreeLibrary");

MEMORY_BASIC_INFORMATION MemInfo;

// hey watch where you're going
if ((dwAddress == lpLoadLibraryA) || (dwAddress == lpLoadLibraryW) || (dwAddress == lpExitProcess) || (dwAddress == lpFreeLibrary))
{
// obviously it shouldnt be pointing to these functions
return true;
}

// check for memory protection type
if (VirtualQuery((LPCVOID)dwAddress, &MemInfo, sizeof(MemInfo)))
{
// since injected code wont have MEM_IMAGE flag,
// we'll check for that
if (MemInfo.Type != MEM_IMAGE) return true;
}

return false;
}

void __hook_BaseThreadStart(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameters, DWORD Unknown)
{
// suspicious address ?
if (IsSuspiciousAddress((DWORD)lpStartAddress))
{
// gotcha
cout << "Suspicious thread blocked" << endl
<< " lpStartAddress: 0x" << hex << lpStartAddress<< endl
<< " lpParameters: 0x" << hex << lpParameters << endl
<< endl;

// kill this thread
ExitThread(NULL);
}
else
{
// seems legitimate
__asm
{
push lpParameters
push lpStartAddress
push Unknown
jmp BaseThreadStart
}
}
}

void TestThread(DWORD lpParameters)
{
// verify the parameter
if (lpParameters == 0x1337C0DE)
{
// okay CreateThread test passed
cout << endl << "TestThread: 0x" << hex << lpParameters << " ... pass" << endl
<< endl
<< "Now grab your favorite injector and inject stuff into me." << endl
<< endl;
}
else
{
// oh no, something went seriously wrong
cout << endl << "TestThread: 0x" << hex << lpParameters << " ... failed" << endl
<< endl
<< "Invalid parameter passed to TestThread" << endl
<< endl;
}
}

int main()
{
cout << "BaseThreadStartThunk: 0x" << hex << BaseThreadStartThunk << endl;
cout << "BaseThreadStart: 0x" << hex << BaseThreadStart << endl;

// hook BaseThreadStart function
PatchCode_Jmp(BaseThreadStartThunk_Jmp, (DWORD)__hook_BaseThreadStart);

// make sure we dont block legitimate CreateThread call
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)TestThread, (LPVOID)0x1337C0DE, NULL, NULL);

Sleep(INFINITE);
return 0;
}
Show details Hide details

Change log

r39 by opcode0...@hotmail.com on Nov 22, 2008   Diff
[No log message]
Go to: 
Project members, sign in to write a code review

Older revisions

All revisions of this file

File info

Size: 3331 bytes, 116 lines
Hosted by Google Code