阅读:4467回复:19
进程注入dll的办法
难得发一个非原创帖...
说到dll的inject 当然方法很多 但是总找不到一个完美的解决方案 比如appinit_dll的reg方式需要映射user32.dll而且是所以映射了user32.dll的进程.不过却有一个好处.就是能在进程加载的第一时间inject到目标进程. 而诸如hook和remote thread的方式却不能在第一时间inject到目标进程.虽然可以使用createprocess的方式先suspend目标进程然后再inject.再resume的方式... 但是如果目标进程再额外的写一个helper程序,这个helper程序只作一件事情就是再create一个新的process的话,这种方式就完全失效了.... 说了这么多.实际是这样的. 许多的java程序都有写一个custom loader,作用就是加密自己的代码.但是不幸的是.不管怎样,传递给jvm的代码必然是没有加密过的代码,而这种代码是能够用很多反编译器获得源代码的.所以如果能hook到custom loader传递给jvm解密过的代码的函数,就能破解那些所谓加密过的程序. 嗯.现在函数已经找到,软件也已经被我破解了.注册机也都已经作好了.但是我想找一个更好的更智能的方法来获取这份未加密过的代码.而不是像我现在用的这种softice下断点,然后保存到文件这种需要人介入的方法. 其实写一个dll然后inject到java的进程里面,hook掉那个函数,然后保存这些未加密的代码就行了. 但是,这个dll必须要在进程启动的时候inject到java的进程里面,因为代码加载到jvm的时机几乎都是在进程启动的时候,等到进程启动完成了,就几乎很少有再加载代码了. 现在我修改了jvm.dll的import table,加入了我的dll的一个函数,这个函数是无所谓的,因为从来都不调用他. 这样的话,我的dll就跟jvm.dll关联到了一起,要用我的这个dll的功能的话就必须要修改jvm.dll这个文件,很显然这个不是一个好的办法 大家有没有什么更好的办法. |
|
最新喜欢:threeb... |
沙发#
发布于:2005-03-11 11:42
我使用下面的方法:
PsSetCreateProcessNotifyRoutine + CreatRemoteThread 目前感觉还可以,但总觉得还是不是很完善。 其实现在很多的应用软件(QQ、瑞星杀毒等)好像都应用了dll注入,也不知他们用的是哪种招式。 |
|
|
板凳#
发布于:2005-03-11 13:08
其实现在很多的应用软件(QQ、瑞星杀毒等)好像都应用了dll注入,也不知他们用的是哪种招式。fsfile你对瑞星有研究吗?我有问题和你探讨关于瑞星的。 |
|
|
地板#
发布于:2005-03-11 13:23
难得发一个非原创帖... 我简化一下: 前提:新建的进程的主线程还没执行,知道了进程的PID,主线程的pid。 如何实现自己的一段代码替换主线程的代码?效果达到: a = mycode(); if(a) { goto srcCodePart; } else { exit(0); } srcCodepart : XXXXX:XXXX |
|
|
地下室#
发布于:2005-03-11 13:27
fsfile你对瑞星有研究吗?我有问题和你探讨关于瑞星的。 哦,基本没研究过,不过很想研究,呵呵 |
|
|
5楼#
发布于:2005-03-11 15:14
网上好象有篇文章就是介绍RISING的反编译的.....
|
|
|
6楼#
发布于:2005-03-11 15:30
不知Windows有没有象DOS INT 21中4c00h那样加载但不执行的函数调用,大家知道么?
|
|
|
7楼#
发布于:2005-03-11 17:34
在 www.phrack.org上的67期有这篇文章,在本站的专栏中也转了,只是文件hook部分。讲怎样通过 service table hook kernel函数。
|
|
|
8楼#
发布于:2005-03-11 18:26
看样子似乎是发错了地方
呵呵... 因为是个app层次的东西 所以kernel ring0的方法就不想去考虑了 当然..有了ring0.还有什么东西是不能强行hijack的. 说到ring3级的dll inject的程序. 我所知道的 spy++...用的是setwindowhook的方式 所谓珊瑚虫显ip qq则是createprocess 然后suspend然后inject然后resume的模式 而diablo2 著名的d2hack it程序则是修改window procedure然后发送一个WM_APP然后在目标进程里面创建一个新线程的方法来作的 也几乎就涵盖了大部分我所知道的ring3的dll inject的方式. 个人认为珊瑚虫显ip qq的方法是比较完美的. 可惜对我手头上的这个软件却不太有用 因为这个exe文件就几行..构造一个command line,然后用winexec调用java.exe传递那个command line进去. 这也是大多数java程序的使用方式. 当然可以修改这个exe就能达到想要的效果.但是我是想写一个通用的破解java的vm的程序而不是只是针对这一个软件. 看起来似乎目标定得不太对 |
|
9楼#
发布于:2005-03-12 08:38
对于这种方式
1、而诸如hook和remote thread的方式却不能在第一时间inject到目标进程.虽然可以使用createprocess的方式先suspend目标进程然后再inject.再resume的方式... 但是如果目标进程再额外的写一个helper程序,这个helper程序只作一件事情就是再create一个新的process的话,这种方式就完全失效了.... 我觉得只能再同时Hook createprocess联合使用 2、其实写一个dll然后inject到java的进程里面,hook掉那个函数,然后保存这些未加密的代码就行了. 但是,这个dll必须要在进程启动的时候inject到java的进程里面,因为代码加载到jvm的时机几乎都是在进程启动的时候,等到进程启动完成了,就几乎很少有再加载代码了. 现在我修改了jvm.dll的import table,加入了我的dll的一个函数,这个函数是无所谓的,因为从来都不调用他. 这样的话,我的dll就跟jvm.dll关联到了一起,要用我的这个dll的功能的话就必须要修改jvm.dll这个文件,很显然这个不是一个好的办法 我觉得这样是不是好些,我先加载一个我自己做的Java程序,这样java.exe和jvm.dll都被加载到内存中,然后对这个jvm.dll注入,修改它的输出表。然后启动要解密的java程序,这时由于dll在内存中只存在一份,新启动的进程只是将内存中你已注入的jvm.dll映射到新启动的进程空间,并连接,这样是不是算第一时间注入,同时又不用修改jvm.dll文件呢? |
|
|
10楼#
发布于:2005-03-12 09:29
那个虫的是用动态修改pe导入表弄的,最早是在zoudan.com上见过.
|
|
|
11楼#
发布于:2005-03-13 05:06
zoudan得方法似乎是静态修改得import table的吧
他改过qq.exe文件本身 珊瑚虫的版本似乎用的是动态注入dll到qq进程 然后在dll里面修改了qq文件 他使用的原版qq...自己用一个loader程序完成dll的注入 楼上的楼上那个先运行一个java.exe的办法行不通 虽然系统会共享image 但是有条件限制的 第一就是必须是同一个文件,指路径相同,而不是文件内容相同 第二被共享的文件必须要被加载到默认地址,不能被重定位 因为共享是基于section的 而按照大多数文件系统的实现.对于有着相同路径的文件共享他的 SECTION_OBJECT_POINTERS...所以想要共享image,则必须要使用相同路径的文件..如果使用绝对路径调用LoadLibrary.你的方法就没有用了... 然后image必须要被加载到默认地址,如果被重定位的话,ntdll会修改大量的文件内容.由于copy on write机制使得你几乎就完整的拥有了一份拷贝...失去了共享的作用 最后一旦你修改了第一个jvm.dll..你拥有的是一份经过copy on write得到干净的不共享的page..第二个jvm.dll的内容是跟其原始内容一样的.. 思前想后..还是静态修改了jvm.dll的import table.方便快捷. 当然了.如果有ring0的权限.这一切都好办了. 不过毕竟是一个app层面上的东西 如果要人家大费周折..用administrator权限安装一个驱动然后再怎样怎样还不如提供一个修改过的dll,或者提供一个用于修改dll的程序来得方便(似乎有不用驱动就能获取到ring0权限的方法?对这些问题我一向不太关心..呵呵) p.s.第一次把自己破解过的程序的注册机发给别的人. 感觉自己好可耻..要被那些辛辛苦苦作软件的人唾骂了. 精神上匿了吧(-.-b) |
|
12楼#
发布于:2005-03-14 11:49
第一就是必须是同一个文件,指路径相同,而不是文件内容相同
有关这个问题确实存在 第二被共享的文件必须要被加载到默认地址,不能被重定位 然后image必须要被加载到默认地址,如果被重定位的话,ntdll会修改大量的文件内容.由于copy on write机制使得你几乎就完整的拥有了一份拷贝...失去了共享的作用 最后一旦你修改了第一个jvm.dll..你拥有的是一份经过copy on write得到干净的不共享的page..第二个jvm.dll的内容是跟其原始内容一样的.. 首先Copy on Write机制对于DLL的实现,仅限于.data与.bss节区, .text代码区不是这样的,是公共的。.data与.bss节区由于不同进程需要有自己的数据,因而一旦另外进程要写,便形成副本。 然后image必须要被加载到默认地址,即便加载到其他地址,.text代码节区也是共享的,记得我们调用完LoadLibrary后,我们要用GetProcAddress取得其中输出函数的地址,然后调用。如果是静态装载DLL,那么在EXE文件加载时进行连接工作。中介就是DLL有个Import Address Table。如果不加载到默认位置,代码区就COW了,不能共享。那么,我们经常做DLL,有几个人去修改默认的加载起始虚地址,这样冲突这么多,怎么能发挥DLL动态连接的作用,岂不有违微软设计之初衷。 而且,在连接DLL时有一个大家经常不用的参数,就是指定节区属性。 我如果使用/section:.bss,S就能把DLL模块中的未初始化数据节区设置成共享的,而非COW的。这样所有使用该DLL的应用程序都只有一份.bss数据,都可以影响数据的值。如果有某个应用程序无法将此DLL加载到默认地址,是不是这个共享方法就失效了呢?为了实现这种情况,难道还要用个LPC吗? |
|
|
13楼#
发布于:2005-03-14 14:31
楼上
copy on write是对整个dll文件一起设置的 这个很容易确认 你写个程序试试就知道了 __asm int 1 VirtualProtect(Addr,len,PAGE_READWRITE,&savedProctect); Addr[0] = xxx; VirtualProtect(Addr,len,savedProctect,&savedProctect); int 1 第一个int 1下来了 用page Addr看看他的物理地址是什么 然后在第二个int 1的地方再看看他的物理地址是什么就知道了 当然得在softice里面 i1here on 至于非默认基址不共享的问题 确实如你说说....如果被重定位确实不能被共享 这个也行容易判断... 你自己多写几个动态链接库..全部默认base address 分别用不同的顺序动态加载他们 然后用page命令看看就明白了 这也就是为什么windows提供的几乎全部的dll比如ntdll,kernel32.dll,user32.dll,ole32.dll等等等等都有不同的基址....更有甚者如果上述4个dll如果必须被重定位的话..很不幸...如果静态链接..那你的exe文件将不能运行.进程会直接结束.如果动态加载...Load函数不会成功... 至于系统里面提供的dll的base address 在我的印象里面是有办法获取一份完整的文档描述每个dll的默认地址以及他说占据的空间大小的.方便让你为自己的dll选择一个恰当的base address 至少我是看过这样的一个文件的 可惜一下子想不起来是用什么办法在什么地方看到这个文档的了.. 只是在nt跟2k的源代码里面搜索到了他们为每个dll指定的地址 不过那些地址已经跟我现在用的系统里面的dll地址大不相同了 至于实际情况下..重定位的情况还是发生的比较小的 发生重定位的一般都是些自己实现的dll 用vc随便attach 一个process看看他的module list就知道了 如果某个module有被重定位的话.vc会显示一个特别的图标在上面.. 正是因为ms为几乎全部的系统dll都分别设置了不同的base address 所以才有那么多的共享 虽然ms从来不说...但是很明显...大部分的lib实现者都会为他的dll尽量选择一个不和别的dll冲突的地址 比如mfcxx.dll比如msvcrt.dll比如jvm.dll这些都不是使用的默认base address 至于你说text共享的问题 再举一个例子...如果你在调试某个程序,设置了一个断点.都知道调试器在那里插入了一个int 3(这个应该不会有疑问了吧,int 3的代码字节是0xcc,看看就明白了)..如果代码被共享的话..岂不是所有共享了这份代码的进程那里都有一个int 3? 如果没有附加调试器的进程执行到这个int 3的话.多数情况下他就跳出一个对话框然后异常结束了.... 实际上因为copy on write机制的作用..使得被调试器修改的代码是一个全新的page..不被别的进程共享的page..而别的进程继续使用原来的page.... 至于编译的时候设置还是不设置base address..这个问题. dll得作用不仅仅只是为了共享那么一点点内存而存在的. 虽然设计dll的初衷确实如此...不过要知道9x系统上面共享得方法是完全不同于nt系列得...而且9x上面也不支持copy on write..9x在dll加载得时候就会全新的分配地址空间..而不是像nt一样要被延迟到被修改的时候 另外通常的..对于一个lib的dll...lib的作者都会为其选择一个非默认的base address..至少是在release模式下应该如此. 很多时候..既便是大家都那样作.那也不一定就是正确的 以上 |
|
14楼#
发布于:2005-03-14 15:31
不过要知道9x系统上面共享得方法是完全不同于nt系列得...而且9x上面也不支持copy on write..9x在dll加载得时候就会全新的分配地址空间..而不是像nt一样要被延迟到被修改的时候
看来真是老了,9x下的东西迈不动路了。。。哎。。。 |
|
|
15楼#
发布于:2005-03-14 17:21
看来Windows还可以改进,修改DLL代码时COW是必要的,但加载基地址可以改进为可以共享的
|
|
|
16楼#
发布于:2005-03-24 10:56
楼上 9x上也是支持copy on write的,看一下Windows 95 System Programming SECRENTS |
|
|
17楼#
发布于:2005-04-14 11:00
在Windows2000下修改了一个应用进程2G内核空间的代码,别的进程的内核空间的代码是不是也相应的被修改了?
|
|
18楼#
发布于:2005-04-14 14:57
在Windows2000下修改了一个应用进程2G内核空间的代码,别的进程的内核空间的代码是不是也相应的被修改了? 肯定,内核空间大家是一样的 |
|
|
19楼#
发布于:2008-10-25 03:46
反正我就是再hook CreateProcess的……
|
|