gpt4 book ai didi

c++ - x86 asm 访问和编辑 __declspec(naked) 函数中的 stdcall 函数参数

转载 作者:太空狗 更新时间:2023-10-29 21:09:54 28 4
gpt4 key购买 nike

我使用以下代码为“NtCreateSection”函数制作了一个 WOW64 系统调用 Hook :

#include "Funcs.h"
#include <cstdio>
#include <Windows.h>

const int PAGE_SIZE = 0x1000;
const int SYSCALL_INTERCEPT = 0x4A;
const int NUM_WOW64_BYTES = 0x9;

using pNtCreateSection =
NTSTATUS (NTAPI*)(PHANDLE SectionHandle, ULONG DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
PLARGE_INTEGER MaximumSize, ULONG PageAttributess, ULONG SectionAttributes, HANDLE FileHandle);
pNtCreateSection NtCreateSection = nullptr;

DWORD_PTR dwWow64Address = 0;
LPVOID lpJmpRealloc = nullptr;
ULONG SectionAttributes;

void __declspec(naked) NtCreateSectionHook()
{
__asm
{
pushad
}

fprintf(stderr, "NtCreateSectionHook called !\n");

__asm
{
popad
jmp lpJmpRealloc
}
}

DWORD_PTR __declspec(naked) GetWow64Address()
{
__asm
{
mov eax, dword ptr fs:[0xC0]
ret
}
}

void __declspec(naked) Wow64Trampoline()
{
__asm
{
cmp eax, SYSCALL_INTERCEPT
jz NtCreateSectionHook
jmp lpJmpRealloc
}
}

LPVOID CreateNewJump(const DWORD_PTR dwWow64Address)
{
lpJmpRealloc = VirtualAlloc(nullptr, PAGE_SIZE, MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);

(void)memcpy(lpJmpRealloc, (const void *)dwWow64Address, NUM_WOW64_BYTES);

return lpJmpRealloc;
}

void EnableWow64Redirect(const DWORD_PTR dwWow64Address, const LPVOID lpNewJumpLocation)
{
unsigned char trampolineBytes[] =
{
0x68, 0xDD, 0xCC, 0xBB, 0xAA, /*push 0xAABBCCDD*/
0xC3, /*ret*/
0xCC, 0xCC, 0xCC /*padding*/
};

memcpy(&trampolineBytes[1], &lpNewJumpLocation, sizeof(DWORD_PTR));
WriteJump(dwWow64Address, trampolineBytes, sizeof trampolineBytes);
}

void WriteJump(const DWORD_PTR dwWow64Address, const void *pBuffer, size_t ulSize)
{
DWORD dwOldProtect = 0;
(void)VirtualProtect(reinterpret_cast<LPVOID>(dwWow64Address), PAGE_SIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);
(void)memcpy(reinterpret_cast<void *>(dwWow64Address), pBuffer, ulSize);
(void)VirtualProtect(reinterpret_cast<LPVOID>(dwWow64Address), PAGE_SIZE, dwOldProtect, &dwOldProtect);
}

int main(int argc, char *argv[])
{
const auto hModule = GetModuleHandle(L"ntdll.dll");
NtCreateSection = reinterpret_cast<pNtCreateSection>(GetProcAddress(hModule, "NtCreateSection"));

dwWow64Address = GetWow64Address();

const auto lpNewJumpLocation = CreateNewJump(dwWow64Address);
EnableWow64Redirect(dwWow64Address, static_cast<LPVOID>(Wow64Trampoline));

//Test syscall
HANDLE hSection;
NtCreateSection(&hSection, SECTION_ALL_ACCESS, nullptr, nullptr, PAGE_EXECUTE_READWRITE, SEC_COMMIT | SEC_NOCHANGE, nullptr);

getchar();

return 0;
}

代码工作正常,直到我将钩子(Hook)函数更改为此

void __declspec(naked) NtCreateSectionHook()
{
__asm
{
pushad
mov eax, [esp + 28]
mov SectionAttributes, eax
}

fprintf(stderr, "NtCreateSectionHook called !\n");

if ((SectionAttributes & SEC_NOCHANGE) != 0)
{
fprintf(stderr, "SEC_NOCHANGE found !\n");
}

__asm
{
popad
jmp lpJmpRealloc
}
}

我的代码中的问题是 pushad 指令与 esp 混淆因此我无法再访问堆栈,如果我不使用 pushad/popap 应用程序崩溃了,因为我弄乱了堆栈然后跳转到了真正的函数地址。我想要访问和更改的参数是 NtCreateSection 的第 6 个参数 function .

最佳答案

pushad 不会阻止您访问堆栈。 pushad 将 32 个字节(8 个寄存器,每个 4 个字节)压入堆栈,因此,pushad 之后的任何偏移量都应通过添加 32 进行更正。

关于c++ - x86 asm 访问和编辑 __declspec(naked) 函数中的 stdcall 函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56608312/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com