LoadLibraryA GetProcAddress 编写代码,获取 VirtualAlloc 并且调用成功
#include <windows.h>
#include <wchar.h>
#include <string.h>
#include <stdio.h>
#include<libloaderapi.h>
int main()
{HMODULE hModule=0;FARPROC space=NULL;hModule = LoadLibraryExA("kernel32.dll", NULL, DONT_RESOLVE_DLL_REFERENCES);if (!hModule){printf("erro!!");}space = GetProcAddress(hModule, "VirtualAlloc");if (!space){printf("erro!!");}else{char* ch = (char*)space();if (ch!=NULL){printf("success!");}}return 0;
}
问题
1.space这里返回的是VirtualAlloc这个函数吗?
2.这里的路径不清楚是否给正确了?
3.假设这个参数给对了,那为什么使用space的时候不是VirtualAlloc的样子
4.VirtualAllocFree的功能怎么实现?(用free吗,因为这里space也是个指针类型)
5.从编译器这边的运行来讲,上述代码没有错误,能正常运行
6.上面图中如果space是VirtualAlloc,这里是没有初始化的
7.FARPROC space函数指针参数都没有
目前:没有用OD动态调试,存在些问题,也没有用IDA看
这两函数没怎么用过
getprocadress,返回的是函数指针
参考c语言,函数指针那节内容
所谓成功,是函数功能正确实现
4.9:昨天为什么编译器没有报错的问题清楚了:FARPROC space,中的space的值只有在space=GetrocAddress(hModule, “VirtualAlloc”);执行后才有意义(指向VirtualAlloc的入口)。只用程序运行过了,space才会指向VirtualAlloc函数,否则是随机值,所以编译器在编译时不检查他的格式和参数,编译器甚至不知道此处调用的是VirtualAlloc()这个函数。既然都不知道将会调用哪一个API函数,所以也就无法检查合法,编译器就不会报错
虽说试着跟进loadLibraryA里面查看,但是转悠半圈一路跟到了loadLibraryExW以后,再到LdrLoadDll的时候就非常复杂看不懂了,去网上找了篇博客https://blog.csdn.net/xiangbaohui/article/details/103743201
对于GetProcAddress,也是根据网上的博客(https://blog.csdn.net/half_face/article/details/51511094)来看,是读取了已经载入的dll的PE文件头(可惜这篇博客引用的看雪论坛的帖子我访问的时候跳到了看雪主页,不知道是已经被删除还是隐藏了),所以不知道具体是如何获得的PE头,但是PE头内部似乎存在[typedef struct _IMAGE_EXPORT_DIRECTORY]里面按照下标对应的方式保存了DLL内部每一个导出函数的导出名、导出序号、内存地址(或者是偏移量也许)
对于loadLibraryA,在LdrLoadDll里面我只看到了LdrpLoadDll和很多个call sub_这样的未命名函数,对于LdrpLoadDll里面有加载文件的call,但是写锁的call没有看到,可能是call sub也可能是汇编直接实现了,用dbg下了个dll载入是断点,然后一直步过,遇到某个call触发了这个dll载入的断点就重载程序重新跟入这个call,重复操作,会进入n个call(跟不完的那种)。然后我想到,这个断点触发的条件可能是内存映射完成的时候,也就是博客里面提到的,dll加载进度到一半的时候,所以这样做估计没有意义就没有继续跟了
改后代码
#include <windows.h>
#include <wchar.h>
#include <string.h>
#include <stdio.h>
int main()
{HMODULE hModule = 0;typedef int (*space)(LPVOID , SIZE_T , DWORD, DWORD);hModule = LoadLibraryExA("kernel32.dll", NULL, DONT_RESOLVE_DLL_REFERENCES);if (!hModule){printf("erro!!");}space AVirtualAlloc = (space)GetProcAddress(hModule, "VirtualAlloc");if (!AVirtualAlloc){printf("erro!!");}else{char* ch = (char*)AVirtualAlloc(NULL,1024, MEM_RESERVE, PAGE_READWRITE);if (ch!=NULL){printf("success!");}}return 0;
}