ce吧 关注:194,520贴子:3,795,764

【c++教学】一步步教你用c++劫持dll调用易语言dll

只看楼主收藏回复

时隔两个多月,当我偶尔看看贴吧的时候,经常看到有人求c++二段的源码,对此我表示很忧桑,也许你们并没有看到dll到底是什么,为什么会有dll这个东西,也许说到这儿有人就懂了,也许早有人已经在用了。
我们通过劫持dll来达到无图标读写,这是dll的延伸,并不是dll的本身应该存在的理由,dll里封装了各种函数,通过接口来实现调用这些函数,那么我们为什么不用c++的劫持dll去调用易语言的功能dll呢,同时,合理分配dll会更有效的管理各个部分,就比如我们把搜索二段的源码封装在一个dll中,由于这个dll不需要基址的更新,所以可以一直调用而不用更新,想想,这样多方便。
那么,问题来了,怎样用易语言实现封装一个dll,从而让我们用c++的dll去调用。
这里有三种,第一种是没有形参的函数,比如void sum(void) 这样的函数,第二种便是有形参的函数,比如 void sum(int a,int b),还有一种是带返回值的,比如int sum(int a,int b)


IP属地:上海来自iPhone客户端1楼2016-09-22 16:13回复
    点进去我们可以看到动态链接库的大致轮廓,我们将“_临时子程序”删了,如下图


    IP属地:上海来自iPhone客户端3楼2016-09-22 16:15
    收起回复
      到这里dll的基本轮廓就出来了,之后便是往里面加功能函数。
      用过易语言的都知道,实现功能肯定会读写内存,这就需要进程ID,通常我们劫持进去进程ID都是取值为-1,因为这里是自身进程,并且将它设为全局变量,因为会一直调用。
      但是这里有几点不一样,一、进程ID不能取值-1,因为不是DNF直接调用这个dll,而是通过c++劫持的dll来调用这个dll。所以这里我们要接着获取DNF的进程ID。二、在这个dll里不能设置全局变量,为什么,很简单,因为每当c++的劫持dll调用这个dll时,只是单纯的调用这个dll里的一个函数,并没有完全打开这个dll里的所有内容,就算定义了全局变量,下次也会找不到这个值。
      所以应该怎么做呢,这不简单么,我们每次都获取进程一次不就行了。


      IP属地:上海来自iPhone客户端4楼2016-09-22 16:16
      回复
        【没有返回值,没有形参的函数】
        这里我们用二段为例子。
        二段的易语言源码我想大家都有吧,就算没有百度一搜就一大堆吧,这里我们需要一个易语言模块(只是方便教学用,最好是自己将用到的功能从超级模块源码中提取出来),我们将源码拷贝到dll中,如下


        IP属地:上海来自iPhone客户端5楼2016-09-22 16:16
        回复
          这是原型,我们要对这个函数做一个处理。
          首先我们需要给它进程ID,所以我们直接使用进程ID=取进程ID(“DNF.exe”)就行,并且将这个进程ID设为局部变量。如下图:


          IP属地:上海来自iPhone客户端7楼2016-09-22 16:17
          回复(1)


            IP属地:上海来自iPhone客户端8楼2016-09-22 16:17
            回复
              既然是个dll,我们肯定要通过相关手段去调用这个dll,最常见也是最普遍的方法便是通过Load Library和Free Library了,首先说下Load Library,这是加载这个dll,通过dll名来加载,所以之前的dll名字就不要随意修改了,不然也不好调用。再者,加载完dll我们也是通过函数名去调用这个dll里的功能函数的,所以一定要确保函数名书写正确,调用完以后,如果不Free Library的话,这个dll会一直处于加载状态,最简单的测试方法就是这时手动删除那个dll,你会发现dll提示正在被使用,同时,加载dll的过程中,原c++dll里的功能也无法使用,你可以尝试按键,你会发现之前的监视按键都不奏效。所以,加载完的dll一定要释放它。


              IP属地:上海来自iPhone客户端12楼2016-09-22 16:20
              回复
                函数原型如下:
                HINSTANCE hDllInst = LoadLibrary(TEXT("搜索.dll"));
                if (hDllInst)
                {
                typedef int (WINAPI *MSGBOX)();
                MSGBOX MsgBox = NULL;
                MsgBox = (MSGBOX)GetProcAddress(hDllInst, "一段");
                if (MsgBox)
                {
                MsgBox();
                }
                FreeLibrary(hDllInst);
                }


                IP属地:上海来自iPhone客户端13楼2016-09-22 16:21
                回复
                  从上面我们可以很容易的看出来哪个部分是dll名,那个部分是dll里的函数名,


                  IP属地:上海来自iPhone客户端14楼2016-09-22 16:21
                  回复
                    这便是一个完整的没有形参,没有返回值的函数的调用过程,写好之后,将之前编译的“搜索.dll”也放到DNF的根目录,也就是和c++劫持dll同一个目录里。


                    IP属地:上海来自iPhone客户端17楼2016-09-22 16:23
                    回复
                      滴滴


                      IP属地:广东19楼2016-09-22 16:23
                      回复


                        IP属地:上海来自iPhone客户端20楼2016-09-22 16:23
                        回复


                          IP属地:上海来自iPhone客户端22楼2016-09-22 16:24
                          回复
                            大家看到了什么,我将最后两行注释了,为什么注释了?
                            这是一个call,主要是为了将徽章的属性写进一个空白地址里,
                            “Mov_Ptr_EAX(4198144)”,便是这句代码的作用,其中4198144就是空白地址,你不必去了解怎么讲数据写进了空白地址,你只需要知道这个时候,空白地址(4198144)里已经有内容了就足够。
                            我们继续,这里需要将读取的“徽章代码”和“徽章地址”的值暂时存起来,方便别的函数调用,那我们能在易语言的dll里读么?答案是当然能,但是却不能将读取到的值保存下来,既然别的函数需要这个值,那么我们就要想办法保存这两个值。
                            好,我们为何不在c++的dll读取两个值呢,前面说了,当执行了这个call后,空白地址就已经不是空白的了,那么我们在c++的dll里便可以直接读取这两个值(其实就只有“徽章地址”用到了,但这里我们先不管这些)。我们在c++的Project里加入两个全局变量。


                            IP属地:上海来自iPhone客户端23楼2016-09-22 16:24
                            回复
                              我也来学习下,C+++


                              来自Android客户端24楼2016-09-22 16:25
                              回复