白影33 发表于 2020-3-29 14:07

用hook的方法干掉vmp对系统dll的修改

本帖最后由 白影33 于 2020-3-29 19:27 编辑

vmp版本3.1,实验系统win10x64,
前几天我发了个vmp反内存补丁的文章,为了免得再踩到坑,我就想把全部的修改系统的点找出来。
确定vmp修改系统dll使用的函数是WriteProcessMemory,再od里下这个函数的断点,
调试过程就略去了,(其实就是看它写的地方是不是系统领空,很无聊,就不占大量的篇幅了)。

最后确定vmp对系统领空的dll修改了7次,如果像那篇里把修改处用WriteProcessMemory写回来,代码就多了,
而且win7,win10系统的dll有所不同,位置和内容也有所不同,那样要改的也太多了,
就不能用这种原始粗暴的方式了,那就用hook的方法。

说代码前先说我的hook思路:
先将WriteProcessMemory的函数头修改,跳到我的代码处,我的代码保存寄存器,保存堆栈,进行判断是否为系统领空,
如果是,恢复寄存器,恢复堆栈,修改eax为1(vmp会检查返回值,不是1就会结束),返回到vmp call WriteProcessMemory下一句
如果不是,恢复寄存器,恢复堆栈,模拟执行被覆盖的函数头,返回到修改的函数头的下一句。

修改函数头的函数代码
void HookWrite()
{

      BYTE chNewCode = { 0 };
      DWORD dwWrite = 0;
      DWORD dwOldProtect = 0;
      DWORD g_dwOldProtect = 0;


      DWORD dwIdNew = GetCurrentProcessId(); //获取进程ID
      HANDLE hand1 = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwIdNew);//通过进程ID获取句柄

      temp1 = (DWORD)*Fwrite;//将判断函数地址放入temp1
      distemp = &temp1;//再将temp1地址放入distemp 因为ff 15 的call是跳去地址里存放的那个地址.
      chNewCode = 0xFF;   //call
      chNewCode = 0x15;
      memcpy(chNewCode + 2, &distemp, sizeof(DWORD));//将地址的地址复制到ff 15后

      
      AWrite = GetProcAddress(LoadLibraryA(TEXT("Kernel32.dll")), "WriteProcessMemory");//获取WriteProcessMemory 函数地址
      
      VirtualProtect(AWrite, 20, PAGE_EXECUTE_READWRITE, &g_dwOldProtect);//修改内存属性为可写可读
      

      WriteProcessMemory(hand1, AWrite, chNewCode, 6, &dwWrite);//对WriteProcessMemory 进行写入
      VirtualProtect(AWrite, 20, g_dwOldProtect, &dwOldProtect);//将内存属性复原


}

我的函数代码
__declspec(naked) void WINAPI Fwrite()
{
      __asm
      {

            
                        mov eax, esp         //将esp放入eax
                        add eax, 0xc         //让eax内的地址指向WriteProcessMemory的第二个参数
               
                        pushad            //保存寄存器
                        pushfd            
                        mov tfwriteEsp, esp//保存堆栈
                        
                        add eax, 0x3      //让eax指向WriteProcessMemory的第二个参数的第一个字节
                        mov ebx, 0         //ebx清0,用于存放WriteProcessMemory的第二个参数的第一个字节
                        movzx bx, byte ptr ds : //将WriteProcessMemory的第二个参数的第一个字节放入ebx的低位
                        mov flagwrite, ebx      //保存这个字节
      }
      if (flagwrite > 0x69)//判断WriteProcessMemory的第二个参数的第一个字节是否大于69来确定是否为系统空间,
      {
                __asm
                {
                        mov esp, tfwriteEsp//如果是系统空间,恢复堆栈
                              popfd          //恢复寄存器
                              popad
                              pop eax       //将我的call的返回地址pop掉
                              mov eax, 1   //修改返回值为1,如果不为1程序会结束
                              retn 0x14       //返回到vmp call WriteProcessMemory下一句

                }
      }
      else
      {
                __asm
                {
                        mov esp, tfwriteEsp//如果不是系统空间,复原堆栈
                              popfd         //复原寄存器
                              popad         

                              retn          //返回到修改的函数头的下一句。



                }

      }



}
这是个dll,其他的文件上个帖子有,就是hook的dll换成这个就行了,
最后上个效果图
hook前

hook后


SoulKingLHW 发表于 2020-5-1 03:34

那年夏天52 发表于 2020-4-30 13:55
楼主这篇帖子标题中的vmp修改系统dll,是安装了vmp的电脑系统会被修改,还是使用加了vmp的应用会被修改呢

VMP壳的软件会修改软件调用系统DLL 函数地址!

白影33 发表于 2020-3-29 15:57

冥界3大法王 发表于 2020-3-29 15:32
不会兰屏吧,louli搞得心都碎了。

不会,vmp改了这么多都没事,我就改一个,反正我没蓝

wadsq1081 发表于 2020-3-29 14:30

学习一下大神

xie83544109 发表于 2020-3-29 14:33

{:1_927:}
多谢楼主分享哟

Mandrake 发表于 2020-3-29 15:30

太深奥了,看不懂{:1_907:}

冥界3大法王 发表于 2020-3-29 15:32

不会兰屏吧,louli搞得心都碎了。

hyoulin68 发表于 2020-3-29 15:44

学习一下大神

律政先锋Snake 发表于 2020-3-29 16:33

win10系统的dll有所不同,位置和内容也有所不同。

小橙紫 发表于 2020-3-29 16:54

知其然,知其所以然,希望楼主多分享一些技术贴

小橙紫 发表于 2020-3-29 17:06

向大佬致敬,这个还是蛮牛的
页: [1] 2 3
查看完整版本: 用hook的方法干掉vmp对系统dll的修改