解决办法一:GetProcAddress函数返回值总为NULL

  一直为NULL吾亦莫名其妙。网上说加入extern "C"的办法并没有解决。具体的解决办法是:

  • 增加def
EXPORTS

getDefaultPrinter @1
  • 调用
#define FUNCTION_INDEX 1
#define FUNCTION_NAME(i) (LPCSTR)MAKEINTRESOURCE(i)

TestFunction function = (TestFunction)GetProcAddress(hDLL, FUNCTION_NAME(FUNCTION_INDEX));

  看着莫名其妙,目前只找到这个办法。使用函数名就是不对。有没有更好的办法呢?请看解决办法二:

VC调用DLL标准范例_柳鲲鹏-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的汇编函数,用于获取Windows环境中的进程信息列表: ```assembly ; 获取进程信息列表 ; 返回值:进程信息结构体指针 getProcessList PROC pushad ; 保存寄存器 xor eax, eax ; 将 eax 设置为 0 mov eax, fs:[eax+0x30] ; 获取PEB地址 mov eax, [eax+0x0C] ; 获取PEB_LDR_DATA结构体地址 mov eax, [eax+0x0C] ; 获取第一个LDR_MODULE结构体地址 findNext: mov ebx, [eax+0x18] ; 获取模块句柄 mov esi, [eax+0x20] ; 获取模块基址 mov ecx, [eax+0x24] ; 获取模块大小 mov edx, [eax+0x28] ; 获取模块入口点 cmp byte ptr [eax+0x30], 0 ; 判断是否为主模块 jne skip ; 不是则跳过 lea eax, [esi+edx-0x1000] ; 计算PE头地址 mov ebx, [eax+0x3C] ; 获取PE头偏移 add eax, ebx ; 计算PE头地址 mov ebx, [eax+0x78] ; 获取导出表地址 add eax, ebx ; 计算导出表地址 mov ebx, [eax+0x20] ; 获取导出函数地址表地址 add eax, ebx ; 计算导出函数地址表地址 mov ecx, [eax+0x24] ; 获取导出函数名称表地址 add eax, ecx ; 计算导出函数名称表地址 mov edx, [eax+0x30] ; 获取导出函数名称地址表地址 add eax, edx ; 计算导出函数名称地址表地址 mov ecx, [eax+0x1C] ; 获取导出函数数量 mov edi, [eax+0x18] ; 获取导出函数名称地址表 xor ebx, ebx ; 将 ebx 设置为 0 searchLoop: mov esi, [edi+ebx*4] ; 获取导出函数名称地址 cmp byte ptr [esi], 0 ; 判断名称是否为空 je skipSearch ; 空则跳过 cmp esi, getProcessListName ; 判断是否为目标函数名称 jne continueSearch ; 不是则继续查找 mov eax, [eax+0x20+ebx*4] ; 获取目标函数地址 call eax ; 调用目标函数 popad ; 恢复寄存器 ret ; 返回 continueSearch: inc ebx ; 继续查找 cmp ebx, ecx ; 判断是否查找完毕 jl searchLoop ; 未完则循环 skipSearch: mov eax, [eax+0x20] ; 获取下一个LDR_MODULE结构体地址 test eax, eax ; 判断是否为 NULL jne findNext ; 不是则继续查找 skip: mov eax, 0 ; 未找到则返回 0 popad ; 恢复寄存器 ret ; 返回 getProcessList ENDP ; 目标函数名称 getProcessListName db "ZwQuerySystemInformation", 0 ``` 使用该函数可以获取进程信息列表。具体使用方法如下: ```c #include <stdio.h> typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER Reserved[3]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; ULONG BasePriority; HANDLE ProcessId; HANDLE InheritedFromProcessId; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; typedef NTSTATUS(WINAPI* PZwQuerySystemInformation)( ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); int main() { HMODULE hNtDll = LoadLibraryA("ntdll.dll"); PZwQuerySystemInformation ZwQuerySystemInformation = (PZwQuerySystemInformation)GetProcAddress(hNtDll, "ZwQuerySystemInformation"); PSYSTEM_PROCESS_INFORMATION pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)getProcessList(); while (pProcessInfo->NextEntryOffset != 0) { printf("Process ID: %d\n", (DWORD)pProcessInfo->ProcessId); printf("Process Name: %wZ\n", &pProcessInfo->ImageName); printf("\n"); pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pProcessInfo + pProcessInfo->NextEntryOffset); } return 0; } ``` 该示例代码使用了Windows API `ZwQuerySystemInformation` 来获取进程信息列表,并且使用汇编函数 `getProcessList` 来调用该 API。最后将进程信息打印到控制台上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳鲲鹏

能给阁下一点帮助,非常荣幸

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值