-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcalc_exec.c
More file actions
137 lines (120 loc) · 4.62 KB
/
Copy pathcalc_exec.c
File metadata and controls
137 lines (120 loc) · 4.62 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
#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 */ \
);
// 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 WinExec_name[] = {'W', 'i', 'n', 'E', 'x', 'e', 'c', '\0'};
uint64_t j = 0;
do {
char *tmp = (char *)((PVOID)krnl32 + name_rva_krnl32[j]);
if (my_strcmp(tmp, WinExec_name) == 0) {
break;
}
j++;
} while (true);
WORD ordinal_WinExec = ordinals_krnl32[j];
DWORD func_rva_WinExec = func_rvas_krnl32[ordinal_WinExec];
typedef UINT(WINAPI *pWinExec)(LPCSTR lpCmdLine, UINT uCmdShow);
pWinExec _pWinExec = (pWinExec)((PVOID)krnl32 + func_rva_WinExec);
char path[] = {'c', 'a', 'l', 'c', '.', 'e', 'x', 'e', '\0'};
ALIGN_STACK();
_pWinExec(path, SW_SHOWNORMAL);
return 0;
}