|  | 
 
| 本帖最后由 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;
 | 
 评分
查看全部评分
 |