| 
 | 
 
 本帖最后由 slore 于 2018-6-23 12:11 编辑  
 
破解方法: 
1.通过微软的符号服务器,找到关键调用函数的位置 
2.UE修改跳转语句 
 
我精简了最必要的组件打包为windisam工具。 
 
 
z01.zip解压后改名z01 
 
windisam.z01.zip
(2.5 MB, 下载次数: 843)
 
 
windisam.zip
(1.75 MB, 下载次数: 950)
 
 
1分钟半破解GIF演示: 
 
 
 
5分钟破解步骤: 
1.解压到任意目录(最好简单没空格纯英文例如D:\windisam) 
 
2.把drvinst.exe放到相同目录 
 
3.拖动drvinst.exe文件到symbol_dl.bat 
 
1,2秒左右,drvinst.pdb文件将生成一个Symbols文件夹 
 
4.剪切drvinst.pdb到windisam根目录 
 
5.拖动drivinst.exe到wdisasm.bat 
 
1,2秒左右,将得到drvinst.asm反汇编文件 
 
6.用记事本打开drvinst.asm文件,查找__imp_pSetupValidateDriverPackage 
补充:有人问32位的,好像32位直接改注册表可以用不需要,既然问了就看了下。 
32位的函数名是__imp__pSetupValidateDriverPackage 
多了一个下划线,所以通用的话,用pSetupValidateDriverPackage就可以了。 
 
 
-   000000014000898F: FF 15 E3 4B 01 00  call        qword ptr [__imp_pSetupValidateDriverPackage]
 
 -   0000000140008995: 8B F8              mov         edi,eax
 
 -   0000000140008997: 85 C0              test        eax,eax
 
 -   0000000140008999: 75 09              jne         00000001400089A4
 
 
  复制代码 
 
调用之后,会有一个test比较,然后是个跳转,处理这个跳转即可。 
 
7. UE打开drvinst.exe,搜索字节序,改之。 
8B F8 85 C0 75 09 41 8B 
改成如下: 
33 C0 8B F8 90 90 41 8B 
 
8. 完。 
 
实际操作非常简单,我就不图文了。 
 
 
 
 
 
 
 
 
为什么这么处理这个跳转的详细说明,请看。以后可以照猫画虎处理RS5,RS6,估计,也许。 
 
============================================================================================== 
一般代码是这样的: 
if (SetupValidateDriverPackage() != 0) { 
   //签名不正确 
   xxxxxxxx 
   return 1 
} else { 
//签名正确 
   return 0 
} 
 
或者 
if (SetupValidateDriverPackage() == 0) { 
   //签名正确 
   xxxxxxxx 
   return 0 
} else { 
  //签名不正确 
  写错误日志 
  return 1 
} 
 
 
 
17133为例: 
  000000014000898F: FF 15 E3 4B 01 00  call        qword ptr [__imp_pSetupValidateDriverPackage] 
  0000000140008995: 8B F8              mov         edi,eax 
  0000000140008997: 85 C0              test        eax,eax 
  0000000140008999: 75 09              jne         00000001400089A4     <- 返回值不为0跳转到00000001400089A4 
  000000014000899B: 41 8B 07           mov         eax,dword ptr [r15] 
  000000014000899E: 41 89 46 10        mov         dword ptr [r14+10h],eax 
  00000001400089A2: EB 3B              jmp         00000001400089DF  <--- 正常处理 
  00000001400089A4: BA 20 00 00 00     mov         edx,20h 
  00000001400089A9: 89 44 24 20        mov         dword ptr [rsp+20h],eax 
  00000001400089AD: 4C 8D 0D 3C 65 01  lea         r9,[??_C@_0DL@BAACEHAK@Driver?5package?5failed?5signature?5@] 
                    00 
  00000001400089B4: 48 8B CD           mov         rcx,rbp 
  00000001400089B7: 44 8D 42 E1        lea         r8d,[rdx-1Fh] 
 
jne跳到00000001400089A4后面是failed,那么就是出错处理,不要让它跳,75改74,签名认证成功跳转到failed,签名不正确不跳转,继续走正常处理。 
或者75 09改成90 90,这个判断跳转不执行,不管驱动签名成功与否,都向下继续走000000014000899B,不知道PE会不有正常正常的驱动签名的文件, 
有的话,建议用90 90吧。另外这里主要是找到关键跳转的位置的方法,汇编怎么改好,我不太懂,可以参考旧版本的修改。。。 
我改的比较暴力,强跳,也有改test eax,eax比较语句的让其判断一直成立。 
 
补充1: 
某老版本的修正如下: 
8B F0 85 C0 75 09 41 8B 
改为 
33 C0 8B F0 90 90 41 8B 
 
17133对应: 
8B F8 85 C0 75 09 41 8B 
可能改成如下: 
33 C0 8B F8 90 90 41 8B 
 
我个人觉得90 90就够了,这个先33 C0,然后把去掉了85 C0 test eax,eax的话,保证eax和正确签名的时候一样为0(也就是签名验证函数返回0,没出错)。 
 
-   000000014000898F: FF 15 E3 4B 01 00  call        qword ptr [__imp_pSetupValidateDriverPackage]
 
 -   0000000140008995: 33 C0              xor         eax,eax     <- 异或运算,eax自己和自己异或结果为0
 
 -   0000000140008997: 8B F8              mov         edi,eax    <- 把0放到edi上,和驱动签名正常时一样,放入0
 
 -   0000000140008999: 90                 nop       <- 没必要判断了,90之,直接往下走,不过eax已经是0了,保持原来的jne  00000001400089A4跳转好像也可以(75 09),跳转条件不成立不会跳的
 
 -   000000014000899A: 90                 nop
 
 -   000000014000899B: 41 8B 07           mov         eax,dword ptr [r15]
 
 -   000000014000899E: 41 89 46 10        mov         dword ptr [r14+10h],eax
 
 -   00000001400089A2: EB 3B              jmp         00000001400089DF
 
  复制代码 
 
补充2(继续往下走): 
  000000014000899B: 41 8B 07           mov         eax,dword ptr [r15]                   <-r15的值保存到eax上 
  000000014000899E: 41 89 46 10        mov         dword ptr [r14+10h],eax          <-eax保存到[r14+10h]上 
  00000001400089A2: EB 3B              jmp         00000001400089DF 
... 
  00000001400089DF: 4C 8D 5C 24 60     lea         r11,[rsp+60h] 
  00000001400089E4: 8B C7              mov         eax,edi         <- edi保存到eax,然后后面就ret了,那么这个函数的返回值是edi,所以上面光90 90的话,只是不写出错日志log,上层函数还会因为返回值是1失败。 
  00000001400089E6: 49 8B 5B 30        mov         rbx,qword ptr [r11+30h] 
  00000001400089EA: 49 8B 6B 40        mov         rbp,qword ptr [r11+40h] 
  00000001400089EE: 49 8B E3           mov         rsp,r11 
  00000001400089F1: 41 5F              pop         r15 
  00000001400089F3: 41 5E              pop         r14 
  00000001400089F5: 41 5C              pop         r12 
  00000001400089F7: 5F                 pop         rdi 
  00000001400089F8: 5E                 pop         rsi 
  00000001400089F9: C3                 ret 
 
 
33 C0是干这个事的,还是要这样改才对。 
 
还原的代码为: 
-       ret = pSetupValidateDriverPackage(...);
 
 -       if ( ret !=0 )
 
 -         SetupWriteTextLog(v9, 0x20u, 1u, "Driver package failed signature validation. Error = 0x%08X");
 
 -       else
 
 -         *(_DWORD *)(var1 + 16) = *(_DWORD *)(var2 + 2104);
 
 -       return (unsigned int)ret;
 
 -     }
 
  复制代码 
 
只改90 90的话,没有if (ret!=0)的判断跳转到写日志,但是返回值是1,主要看上层函数管不管这个值,如果管还可能失败,还看不到日志(Driver package failed signature validation. ) 
- ret = pSetupValidateDriverPackage(...);
 
 - *(_DWORD *)(var1 + 16) = *(_DWORD *)(var2 + 2104);
 
 - return (unsigned int)ret;
 
  复制代码 
 
33 C0 .. 90 90的话,和正常签名效果一样,保存*(_DWORD *)(var1 + 16)且返回值为0 
- ret = pSetupValidateDriverPackage(...);
 
 - ret = ret xor ret;  //ret = 0
 
 - *(_DWORD *)(var1 + 16) = *(_DWORD *)(var2 + 2104);
 
 - return (unsigned int)ret;
 
  复制代码 
 |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |