-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessagebox.c
More file actions
168 lines (149 loc) · 6.03 KB
/
Copy pathmessagebox.c
File metadata and controls
168 lines (149 loc) · 6.03 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <wchar.h>
#include <windows.h>
#include <winternl.h>
#define FUNC __attribute__((section(".func")))
// The 16-bytes stack alignment is required for WinAPI functions
#define ALIGN_STACK() \
__asm__ __volatile__( \
"mov %%rsp, %%rax;" /* Move stack pointer to rax */ \
"and $0xF, %%rax;" /* Check if aligned to 16 bytes */ \
"jz aligned;" /* If aligned, jump to aligned If not aligned, \
adjust the stack pointer */ \
"sub $8, %%rsp;" /* Decrease stack pointer by 8 bytes */ \
"xor %0, %0;" /* Optionally zero out the allocated space */ \
"aligned:" \
: /* No output operands */ \
: "r"(0) /* Input operand (to zero out) */ \
: "%rax" /* Clobbered register */ \
);
// memcpy custom function
FUNC void *mc(void* dest, const void* src, size_t n){
char* d = (char*)dest;
const char* s = (const char*)src;
while (n--)
*d++ = *s++;
return dest;
}
// wchar comparison custom function
FUNC int my_wcsicmp(const wchar_t *s1, const wchar_t *s2) {
while (*s1 != L'\0' && *s2 != L'\0') {
wchar_t c1 = (*s1 >= L'a' && *s1 <= L'z') ? *s1 - 32 : *s1;
wchar_t c2 = (*s2 >= L'a' && *s2 <= L'z') ? *s2 - 32 : *s2;
if (c1 != c2) {
return (c1 < c2) ? -1 : 1;
}
s1++;
s2++;
}
if (*s1 == L'\0' && *s2 == L'\0') return 0;
return (*s1 == L'\0') ? -1 : 1;
}
// str comparison custom function
FUNC int my_strcmp(const char *str1, const char *str2) {
while (*str1 != '\0' && *str2 != '\0') {
if (*str1 != *str2) {
return (*str1 < *str2) ? -1 : 1;
}
str1++;
str2++;
}
if (*str1 == '\0' && *str2 == '\0') {
return 0;
}
return (*str1 == '\0') ? -1 : 1;
}
// Function to retrieve DLL from PEB
FUNC PLDR_DATA_TABLE_ENTRY GetDllLdr(PPEB_LDR_DATA ldr, wchar_t *name) {
PLIST_ENTRY head = &ldr->InMemoryOrderModuleList;
PLIST_ENTRY item = head->Blink;
if (item == NULL || item == head) {
return NULL;
}
PLDR_DATA_TABLE_ENTRY dll = NULL;
do {
dll = CONTAINING_RECORD(item, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if (dll == NULL) return NULL;
if (my_wcsicmp(dll->FullDllName.Buffer, name) == 0) {
return dll;
}
item = item->Blink;
} while (item != NULL );
return NULL;
}
// Function to parse PEB
FUNC PPEB GetPEB(void) {
uint64_t value = 0;
asm volatile("movq %%gs:%1, %0"
: "=r"(value) // output
: "m"(*(uint64_t *)0x60) // input
: // no clobbered registers
);
return (PPEB)value;
}
// main function
int start(void) {
PPEB peb = GetPEB();
// Loading of Kernel32.dll
wchar_t krnl32_dll_name[] = {
L'C', L':', L'\\', L'W', L'i', L'n', L'd', L'o', L'w', L's', L'\\',
L'S', L'y', L's', L't', L'e', L'm', L'3', L'2', L'\\', L'K', L'E',
L'R', L'N', L'E', L'L', L'3', L'2', L'.', L'D', L'L', L'L', L'\0',
};
// Get address of krnl32.dll
PLDR_DATA_TABLE_ENTRY krnl32_ldr = GetDllLdr(peb->Ldr, krnl32_dll_name);
PIMAGE_DOS_HEADER krnl32 = (PIMAGE_DOS_HEADER)krnl32_ldr->DllBase;
// Get address of PE headers
PVOID pe_hdrs_krnl32 = (PVOID)((PVOID)krnl32 + krnl32->e_lfanew);
// Get Export Address Table RVA
DWORD eat_rva_krnl32 = *(PDWORD)(pe_hdrs_krnl32 + 0x88);
// Get address of Export Address Table
PIMAGE_EXPORT_DIRECTORY eat_krnl32 = (PIMAGE_EXPORT_DIRECTORY)((PVOID)krnl32 + eat_rva_krnl32);
// Get address of function names table
PDWORD name_rva_krnl32 = (PDWORD)((PVOID)krnl32 + eat_krnl32->AddressOfNames);
// Get function ordinal
PWORD ordinals_krnl32 = (PWORD)((PVOID)krnl32 + eat_krnl32->AddressOfNameOrdinals);
// Get function pointer
PDWORD func_rvas_krnl32 = (PDWORD)((PVOID)krnl32 + eat_krnl32->AddressOfFunctions);
// Get function name
char LoadLibraryW_name[] = {'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'W', '\0'};
uint64_t j = 0;
do {
char *tmp = (char *)((PVOID)krnl32 + name_rva_krnl32[j]);
if (my_strcmp(tmp, LoadLibraryW_name) == 0) {
break;
}
j++;
} while (true);
WORD ordinal_krnl32 = ordinals_krnl32[j];
DWORD func_rva_krnl32 = func_rvas_krnl32[ordinal_krnl32];
typedef HMODULE (WINAPI *pLoadLibraryW)(LPCWSTR lpLibFileName);
pLoadLibraryW _pLoadLibraryW = (pLoadLibraryW)((PVOID)krnl32 + func_rva_krnl32);
// Loading of User32.dll from Kernel32 LoadLibraryW function
wchar_t user32_name[] = {L'u', L's', L'e', L'r', L'3', L'2', L'.', L'd', L'l', L'l', L'\0'};
HMODULE hUser32 = _pLoadLibraryW(user32_name);
PIMAGE_DOS_HEADER usr32 = (PIMAGE_DOS_HEADER)hUser32;
PVOID pe_hdrs_usr32 = (PVOID)((PVOID)usr32 + usr32->e_lfanew);
DWORD eat_rva_usr32 = *(PDWORD)(pe_hdrs_usr32 + 0x88);
PIMAGE_EXPORT_DIRECTORY eat_usr32 = (PIMAGE_EXPORT_DIRECTORY)((PVOID)usr32 + eat_rva_usr32);
PDWORD name_rva_usr32 = (PDWORD)((PVOID)usr32 + eat_usr32->AddressOfNames);
PWORD ordinals_usr32 = (PWORD)((PVOID)usr32 + eat_usr32->AddressOfNameOrdinals);
PDWORD func_rvas_usr32 = (PDWORD)((PVOID)usr32 + eat_usr32->AddressOfFunctions);
char MsgBoxW_name[] = {'M', 'e', 's', 's', 'a', 'g', 'e', 'B', 'o', 'x', 'W', '\0'};
j = 0;
do {
char *tmp = (char *)((PVOID)usr32 + name_rva_usr32[j]);
if (my_strcmp(tmp, MsgBoxW_name) == 0) {
break;
}
j++;
} while (true);
WORD ordinal_usr32 = ordinals_usr32[j];
DWORD func_rva_usr32 = func_rvas_usr32[ordinal_usr32];
typedef int (WINAPI *pMessageBoxW)( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
pMessageBoxW _pMessageBoxW = (pMessageBoxW)((PVOID)usr32 + func_rva_usr32);
_pMessageBoxW(NULL, L"Hello world !", L"SUCCESS", MB_OK);
return 0;
}