注意我们这里观察的是XP的kernel32.dll,到win10是有变化的
看了这个函数,似乎是让BasepExeLdrEntry不存在的时候初始化一遍,然后进行对比是否已经加载过这个dll,那么如果加载下一个dll的时候,BasepExeLdrEntry是不是还是非空状态,v3不就仍然保存着上一个dll的地址了吗
看了交叉引用也没发现有哪里把它至0的
有标记,就不加载了
问题在于我刚刚框出的部分没有见到for,那么查map也就不在这里进行查询,有可能的部分就是这个函数内的回调
在里面的确见到了赋值和比较
但是在BasepExeLdrEntry非空的时候,这部分似乎没有被执行?
不符合条件,肯定跳过
那么加载过一次dll,作为全局变量的BasepExeLdrEntry不就保存了上一个dll的数据么,再加载dll的时候又是怎么判断的呢
每个进程都有一个加载map的,对比就知道了加没加过
enumloadmodule就是遍历函数
这个全局变量内部很复杂的
不是简单的dword
是一个结构体的指针
操作系统的全局变量,几乎都是大结构
不过问题在于,这个全局变量在加载第一个dll的时候被赋值过了,那么加载第二个dll的时候,就不会执行if里面的内容,也就是不会遍历,那又如何去判断是否加载过第二个dll呢
那万一是,空才是加载过了呢
这个得调过才懂
不能按正常经验判断
有些结构,头,就有那种标志位
表示状态的
按照分析来说应该是非空加载过了才对
至于动态调试,我的电脑是win10,看到的不太一样
尤其是不知道怎么找全局变量BasepExeLdrEntry的地址
即使是试着把本机的kernel32.dll丢进ida分析,却得不到代码
extrn,也就是本机的kernel32.dll也是引用另一个地方的LoadLibraryExW_0
注意到dbg显示的模块是KernelBase,去找了这个dll
自己部分
https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlinitansistring
LoadLibraryExA
LoadLibraryExW这两个最开始两个分别对ANSI、Unicode的计数字符串进行了初始化然LoadLibraryExA底层调用了LoadLibraryExW,跟进LoadLibraryExW里面又跟进了LoadDll
进里面走了一圈跳出来了,最开始的时候LoadLibraryExW里面调动RtALLocateheap做了一个堆中内存块的分配,最后在RtFreeUnicodeSting中做了个释放
On Windows 10, GetProcAddress calls LdrGetProcedureAddressForCaller.
GetProcAddress进入从LdrGetProcedureAddressForCaller又跳到了EnterCriticalSection
https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-entercriticalsection
这些函数可以了解一下,最关键还是把整体流程整理清楚