Skip to content

Commit b06a9e5

Browse files
committed
Add files
1 parent e3bb35b commit b06a9e5

File tree

7 files changed

+222
-0
lines changed

7 files changed

+222
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# IDE
2+
.clangd
3+
14
# Prerequisites
25
*.d
36

src/defs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#define PE_BASE 0xA40000 // This address is the current PE base of prog_cpp.exe, and will change if you compile the binary yourself.
2+
3+
#define DEREF(x) (*((int *)base_addr + ((int*)x - (int*)PE_BASE)))
4+
#define OFFSET(x) (int*)(base_addr + ((int*)x - (int*)PE_BASE))
5+
#define LOWORD_ALT(x) (*((unsigned short*)&(x)))
6+
7+
#define PTR_FUNC(x) (((void *(*)())OFFSET(x)))
8+
#define INT_FUNC(x) (((int (*)())OFFSET(x)))
9+
#define CHAR_FUNC(x) (((char (*)())OFFSET(x)))

src/dllmain.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <stdio.h>
2+
#include <windows.h>
3+
4+
#include "defs.h"
5+
#include "hooks.h"
6+
7+
// Push DWORD then ret.
8+
BYTE REDIR_OPCODE[] = {0x68, 0x00, 0x00, 0x00, 0x00, 0xc3};
9+
10+
LPVOID redirect_func(LPVOID func_base_addr, LPVOID dst) {
11+
LPVOID func_addr = func_base_addr - PE_BASE;
12+
LPVOID base_addr = GetModuleHandle(0);
13+
LPVOID target_addr =
14+
(LPVOID)((uintptr_t)base_addr + (uintptr_t)func_addr);
15+
DWORD previous_protection;
16+
VirtualProtect((LPVOID)target_addr, sizeof(REDIR_OPCODE),
17+
PAGE_EXECUTE_READWRITE, &previous_protection);
18+
memcpy(&REDIR_OPCODE[1], &dst, sizeof(DWORD));
19+
printf("Opcode: ");
20+
for (int i = 0; i < sizeof(REDIR_OPCODE); ++i) {
21+
printf("0x%02x ", REDIR_OPCODE[i]);
22+
}
23+
printf("\n");
24+
if (!WriteProcessMemory(GetCurrentProcess(), target_addr, REDIR_OPCODE,
25+
sizeof(REDIR_OPCODE), 0)) {
26+
fprintf(stderr, "WriteProcessMemory error: %ld\n", GetLastError());
27+
}
28+
VirtualProtect((void *)func_addr, sizeof(REDIR_OPCODE),
29+
previous_protection, &previous_protection);
30+
FlushInstructionCache(GetCurrentProcess(), 0, 0);
31+
printf("Redirected function 0x%p + 0x%p (0x%p) to 0x%p.\n", base_addr,
32+
func_addr, target_addr, dst);
33+
return func_addr;
34+
}
35+
36+
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
37+
switch (fdwReason) {
38+
case DLL_PROCESS_ATTACH:
39+
// Code to run when the DLL is loaded
40+
redirect_func((LPVOID*)FUNC_ADDR, func);
41+
printf("DLL loaded successfully.\n");
42+
break;
43+
case DLL_PROCESS_DETACH:
44+
// Code to run when the DLL is freed
45+
break;
46+
case DLL_THREAD_ATTACH:
47+
// Code to run when a thread is created during the DLL's lifetime
48+
break;
49+
case DLL_THREAD_DETACH:
50+
// Code to run when a thread ends normally.
51+
break;
52+
}
53+
return TRUE;
54+
}

src/hooks.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <windows.h>
2+
3+
#include "hooks.h"
4+
#include "defs.h"
5+
6+
void *__thiscall func(void *_this) {
7+
int v1; // eax@1
8+
int v3; // [sp+0h] [bp-43Ch]@1
9+
int v4; // [sp+8h] [bp-434h]@1
10+
int v5; // [sp+Ch] [bp-430h]@1
11+
int v6; // [sp+10h] [bp-42Ch]@1
12+
char v7[1032]; // [sp+14h] [bp-428h]@1, 1032 = 0x408
13+
int v8; // [sp+41Ch] [bp-20h]@1
14+
int *v9; // [sp+420h] [bp-1Ch]@1
15+
void *v10; // [sp+424h] [bp-18h]@1
16+
int(__cdecl * v11)(int, int, int, int); // [sp+428h] [bp-14h]@1
17+
int v12; // [sp+42Ch] [bp-10h]@1
18+
19+
int *base_addr = (int *)GetModuleHandle(NULL);
20+
21+
v9 = &v3;
22+
v12 = -1;
23+
v11 = INT_FUNC(0xA41200);
24+
v10 = _this;
25+
v1 = INT_FUNC(0xA41280)(v7); // Segmentation fault
26+
v12 = 0;
27+
v6 = v1;
28+
v5 = INT_FUNC(0xA413F0)(0xA7B300, "One missisipi ");
29+
v4 = INT_FUNC(0xA41810)(v8);
30+
INT_FUNC(0xA41AB0)(INT_FUNC(0xA41AD0));
31+
INT_FUNC(0xA41B30)();
32+
return v10;
33+
}

src/hooks.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#define FUNC_ADDR 0xA41000 // Address of func() from IDA. Will change if you compile the binary yourself. The relative address offset is 0x1000.
2+
3+
void* __thiscall func(void *_this);
4+
5+

src/loader.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <stdio.h>
2+
#include <windows.h>
3+
4+
#define PROGRAM_NAME "prog_cpp.exe"
5+
#define DLL_NAME "my_dll.dll"
6+
#define BUFSIZE 1024
7+
8+
int main(int argc, char *argv[]) {
9+
STARTUPINFO start_info = {sizeof(start_info)};
10+
PROCESS_INFORMATION process_info;
11+
char cmd[BUFSIZE];
12+
13+
// Format passed down to loader to pass to process.
14+
snprintf(cmd, BUFSIZE, "%s", PROGRAM_NAME);
15+
for (int i = 1; i < argc; ++i) {
16+
snprintf(cmd, BUFSIZE, "%s %s", cmd, argv[i]);
17+
}
18+
19+
if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL,
20+
NULL, &start_info, &process_info)) {
21+
LPVOID page = VirtualAllocEx(process_info.hProcess, NULL, BUFSIZE,
22+
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
23+
if (page == NULL) {
24+
fprintf(stderr, "VirtualAllocEx error: %ld\n", GetLastError());
25+
return 1;
26+
}
27+
if (WriteProcessMemory(process_info.hProcess, page, DLL_NAME,
28+
sizeof(DLL_NAME), NULL) == 0) {
29+
fprintf(stderr, "WriteProcessMemory error: %ld\n", GetLastError());
30+
return 1;
31+
}
32+
HANDLE thread = CreateRemoteThread(process_info.hProcess, NULL, 0,
33+
(LPTHREAD_START_ROUTINE)LoadLibraryA,
34+
page, 0, NULL);
35+
if (thread == NULL) {
36+
fprintf(stderr, "CreateRemoteThread error: %ld\n", GetLastError());
37+
return 1;
38+
}
39+
if (WaitForSingleObject(thread, INFINITE) == WAIT_FAILED) {
40+
fprintf(stderr, "WaitForSingleObject error: %ld\n", GetLastError());
41+
return 1;
42+
}
43+
CloseHandle(thread);
44+
if (ResumeThread(process_info.hThread) == -1) {
45+
fprintf(stderr, "ResumeThread error: %ld\n", GetLastError());
46+
return 1;
47+
}
48+
CloseHandle(process_info.hProcess);
49+
VirtualFreeEx(process_info.hProcess, page, BUFSIZE, MEM_RELEASE);
50+
}
51+
}

src/main.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Source code of prog_cpp.exe. A compiled version is provided in the releases. If you compile this yourself, be sure you update PE_BASE in defs.h and FUNC_ADDR in hooks.h.
2+
3+
#include <iostream>
4+
5+
class C {
6+
public:
7+
int a = 0;
8+
int b = 0;
9+
int c[255];
10+
int *d = nullptr;
11+
int stuff = 0;
12+
C(){
13+
std::cout << d << std::endl;
14+
d = new int[300];
15+
std::cout << d << std::endl;
16+
++stuff;
17+
for(int i = 1; i < 255; ++i){
18+
c[i] = i;
19+
if( i == 254){
20+
c[i] = 0;
21+
}
22+
}
23+
for(int i = 1; i < 300; ++i){
24+
d[i] = i;
25+
if( i == 299){
26+
d[i] = 0;
27+
}
28+
}
29+
}
30+
~C(){
31+
std::cout << d << std::endl;
32+
delete[] d;
33+
std::cout << d << std::endl;
34+
++stuff;
35+
}
36+
37+
void play(){
38+
bool c_stop, d_stop;
39+
c_stop = false;
40+
d_stop = false;
41+
for(int i = 0;;++i){
42+
if(c[i] == 0 && !c_stop){
43+
std::cout << "C had " << i + 1<< std::endl;
44+
c_stop = true;
45+
}
46+
if(d[i] == 0 && !d_stop){
47+
std::cout << "D had " << i + 1 << std::endl;
48+
d_stop = true;
49+
}
50+
if(d_stop && c_stop){
51+
break;
52+
}
53+
}
54+
}
55+
};
56+
57+
void func(){
58+
C clae;
59+
std::cout << "One missisipi " << clae.stuff << std::endl;
60+
}
61+
62+
int main(){
63+
func();
64+
C clae;
65+
std::cout << clae.stuff << std::endl;
66+
clae.play();
67+
}

0 commit comments

Comments
 (0)