pxhb 发表于 2015-9-30 18:26

无源码给程序加VMProtect授权

本帖最后由 pxhb 于 2015-9-30 18:37 编辑

   帖子不好编辑,图片上传不了,大家下载看附件里面的pdf吧
         
无源码给程序加VMProtect授权

作为一个新手,一直以来都听说vmp没有源码写代码的情况下加不了授权,事实也确实如此。但最近闲着无聊,想弄一下vmp的授权,就调用汇编做了个小程序,编译后发现,所谓的SDK,好像只是添加了一个导入表的样子,然后编译的时候替换成壳的内部函数,如果是这样,那可不可以理解成,我添加一个导入表到没有源码的程序里面调用也可以呢?经过多次失败和实践,终于成功。
但在没有源码的情况下毕竟很多东西都很难弄,不是实现不了,是太费劲了,比如分解key,获取时间这些,经过自己写代码测试,发现vmp一个强大之处,手动添加vm地址,可以绑定注册码才可以被正确执行,如果没有正确的lic,即使绕过了授权的代码或者修改授权返回值,一样不会被正确执行,提示:
This code requires valid serial number to run.
Program will be terminated. 可以自行修改                                    
这里的关键是通过vmp的一个api传一个参数,也就是注册码的值去决定的,VMProtectSetSerialNumber,这个,那是不是可以理解为我们只要添加这个到其他程序,然后调用就可以呢,想到这里特别兴奋,自己动手简单的弄了一个,发现还真可以,但是又有个问题,我加授权的话不可能每个程序的lic都放到里面吧,这样也太麻烦了,然后想到ReadFile把内容从文件读取,这样的话就会涉及到好几个api,CreateFile、GetFileSize、ReadFile、CloseHandle,在有源码的情况下当然是好实现,一想到是没源码的情况下做这个,呃,有点要命,在和smny大牛的讨论中他提到用GetPrivateProfileStringA来直接读取配置文件内容,这样下来就只用一个api即可实现读取内容,再次特别感谢smny大牛的提示。
下面就是添加区段来实现读取key和设置key内容了,手动在OD写代码确实有点麻烦,每次都弄太费时间,然后想到自己用汇编写好代码,到时候直接添加区段,当然咯,这样的话最好越省事越好,借鉴了看雪http://bbs.pediy.com/showthread.php?t=182964这个帖子的shellcode那种形式来获取api地址,以下代码思路来自于wjuid大牛
assume fs:nothing
xor   ecx,ecx
mov eax,fs:
mov eax,
mov esi,
next_module:
      mov   eax,
      mov   edi,
      mov   esi,
      cmp,cx
      jnznext_module
;****************************************************************************************      
      mov edx,eax   ;eax保存着KERNEL32基址 ,xpwin7 64位通杀
mov eax,(IMAGE_DOS_HEADER ptr ).e_lfanew;得到IMAGE_NT_HEADERS地址
mov eax,(IMAGE_NT_HEADERS ptr ).OptionalHeader.DataDirectory.VirtualAddress;得到导出表RVA
add eax,edx          ;导出表在内存的实际地址
assume eax:ptr IMAGE_EXPORT_DIRECTORY
mov esi,.AddressOfNames
add esi,edx
push 00007373h;在堆栈中构造GetProcAddress
push 65726464h
push 41636F72h
push 50746547h
push esp
xor ecx,ecx
.repeat
    mov edi,
    add edi,edx
    push esi
    mov esi,
    push ecx
    mov ecx,0fh ;GetProcAddress的长度,包括0
    repz cmpsb
    .break .if ZERO? ;找到跳出循环
    pop ecx
    pop esi
    add esi,4
    inc ecx
.until ecx >= .NumberOfNames
pop ecx
mov esi,.AddressOfNameOrdinals
add esi,edx
movzx ecx,word ptr ;取出序数
mov esi,.AddressOfFunctions
assume eax:nothing
add esi,edx
mov esi,
add esi,edx ;得到GetProcAddress地址
movedi,edx
push 00000000
push 41797261h ;在栈中构造LoadLibraryA
push 7262694Ch
push 64616F4Ch
push esp
push edx
call esi ;调用GetProcAddress获取LoadLibraryc地址
;mov edx,ebx
      call _kernel32
      db 'kernel32.dll',0
_kernel32:
      pop ebx
      push ebx
      call eax
    ;    mov edi,eax
      call _GetPri
       db 'GetPrivateProfileStringA',0
_GetPri:
      popebx
      push ebx
      push eax
      call esi
      
      call _keyName
      db '.\Key.ini',0
_keyName:
      pop ebx
      push ebx; ini名字
      push 256h;缓冲区大小
      call _xbuf
_xbuf:
      pop ebx
      add ebx,50h
      push ebx;缓冲区地址
      push 0
      call _strLic
      db 'Lic',0
_strLic:
      pop ebx
      push ebx   ;lic存放名字
      call _strName
      db '授权文件',0
_strName:
      pop ebx
      push ebx;ini配置部分名字         
      
      call eax;Call API获取配置文件里面的key
      
      mov eax,
      call _Callvm
      nop
      
      db 0FFh,25h,11h,22h,33h,44h;这里用来后期修改,vmp的api地址
_Callvm:
      nop
      pop ebx
      push eax
      call ebx
      nop
      push 00401000h ;修改为原来程序的oep地址,可以用jmp xx
      retn   
编译后用CFF或者LoadPE保存下text区段,仅1kb大小,有了前期的分析和准备工作,下面就是开始动手的时候了
一、    添加区段、导入表和修改OEP地址(以xp的记事本为例子)
01、    添加区段
先把notepad.exe拖到od,记录下原来的入口点地址0100739D

再把要加壳的程序拖到LoadPE里面,点区段—从磁盘载入段

选择已经弄好的CheckVmp.Code这个文件,载入后顺便点下编辑区段,复制虚拟地址,00013000,这个改成新的入口点

02、    添加导入表
将vmp的sdk文件VMProtectSDK32.dll和要处理的文件放到同一个文件夹,点下LoadPE的目录---输入表

右键任意点一个已经存在的,然后添加导入表

Dll名字输入VMProtectSDK32.dll
Api名字输入VMProtectSetSerialNumber

然后点下+号添加—确定,返回到LoadPE主界面保存文件,记得入口改成新区段的rav
改完后OD打开发现入口已经改成了我们添加的区段

二、    修改原始的入口点和输入表地址
1、    原始入口点,往下找,找到push 401000,改成原来程序的入口点
也就是push 0100739D
2、    修改输入表地址,找到这行代码
0101310E    FF25 11223344   jmp dword ptr ds:,可能在od里面有点乱,不能直接看到,可以按键盘 Ctrl+方向键向下,按几下就可以看到了,或者直接复制FF25开头那句代码的地址

按Ctrl+N找到VMProtectSetSerialNumber这个导入表,复制地址,修改jmp dword ptr ds:这条代码,改成新的导入表地址
jmp dword ptr ds:
没次添加可能不一样,大家自己根据地址复制,修改完了以后保存修改的这两个地方
修改部分就到此完成,下面就可以用vmp来加壳了
三、    加壳过程
打开vmp,记得设置为专家模式,然后拖已经处理好的exe到里面,点授权管理,生成一下RSA,返回要保存的流程,点+,新建流程,流程这里特别重要,关系到安全性,添加的时候多个都可以,把关键代码都添加一下,如果什么都不知道,至少要填入口点,这里就填入口点吧
也就是之前记录的0100739D,然下面绑定注册码一定要选是,否则搞了半天什么用都没有
到此就完成了,点下保护F9,完成就可以了
最后在授权管理的那里生成一下授权
新建一个key.ini
内容格式如下
[授权文件]
Lic=注册码
把生成的lic放到注册码这里,记得去掉换行哦,
测试下程序就可以看到区别了,有正确lic的情况下正常被执行,没有lic或者lic不是本机绑定的情况下,就是提示错误,即使找到设置lic那些代码,或者入口改成原来的,也是不行的
这只是一个简单的例子,关于获取机器码,可以用一个独立的去获取,我会附上一个给大家,有兴趣的可以在shellcode里面添加,如果还是这么闲着,我会完善一下,看时间了

pdf和例子
   

最后附上一个简单的获取机器码独立exe,下载后需要用vmp加下壳,不然没用哦


pxhb 发表于 2015-11-7 09:08

asong 发表于 2015-11-7 07:44
dll能不能加?exe测试可行,DLL每次打开OD看到的入口都不一样

和exe思路一样,但要注意一下最后的push 入口改完jmp入口地址

Rookietp 发表于 2015-10-1 17:29

pxhb 发表于 2015-9-30 18:39
小菜编程基础差,bang牛你写个自动完成的工具吧,造福人类

{:17_1061:}个人好像如果要SDK,还是在代码中加比较好。

Rookietp 发表于 2015-9-30 18:37

{:17_1062:}坐等楼主出工具,只会用工具=。=

pxhb 发表于 2015-9-30 18:39

Rookietp 发表于 2015-9-30 18:37
坐等楼主出工具,只会用工具=。=

小菜编程基础差,bang牛你写个自动完成的工具吧,造福人类{:1_937:}

赖哥 发表于 2015-9-30 19:17

{:17_1062:}小菜坐等工具

xiawan 发表于 2015-9-30 20:28

技术神,支持,感谢大神的技术~

青霄 发表于 2015-9-30 20:47

请收下我的膝盖{:1_932:}{:1_931:}

cwz 发表于 2015-10-1 10:56

收藏,感谢大神的技术~

ruanjianjl 发表于 2015-10-1 17:06

非常感谢 马上测试

su123 发表于 2015-10-2 09:55

非常感谢{:1_903:}
页: [1] 2
查看完整版本: 无源码给程序加VMProtect授权