00:03
嗯,这节课呢,我们讲一下这个注入和户口啊,那首先呢,我们来讲注入,嗯,那首先呢,要注入的话呢,我们先要了解一个就是动态链接库啊,动态链接库有很多种写法,那我们在这儿呢,就找一个比较方便的方式啊,我们直接创建一个呃,它的这种模板的动态连接库啊,然后D26点击确定。好,他的人员创建,创建完事之后呢,我们现在呢,直接给他来,呃,设置一下。C加加代码生成啊,然后这里设置MTD,这里环节库关掉。应用确定,然后点击重新生成,测试一下效果。好,成功了,然后呢,我们来看一下这个我们这些东西啊,那首先呢,我们需要了解的东西其实并不多啊,这是一个最基础,最基础的默认的一个动态连接库,这个动态链接库里头我们需要比较知熟知的东西呢,就是首先是一个动态链接库的一个入口,就是D啊,这个呢,就相当于我们呃,普通控制台程序的一个妹,或者说是一个WIN32程序的一个温妹啊,然后呢,我们这里边的三个参数呢,我们知道两个就行啊,剩下一个呢,我们属于保留字段啊,我们放在这儿就行了,第一个啊,这个handle啊,这个h model这个东西,这个东西实际上就相当于你这个模块啊,在被加载的时候啊,然后呢,你位于当前的一个虚拟空间里边啊,它的一个所在一个位置啊,其实就是相对于va的啊,这个va呢,指的就是这个address。
01:41
啊,相对于va里边的一个这个地址啊,我们因为我们都知道啊,我们实际上而言呢,一个这个ESE程序在加载到这个我们的这个虚拟内存中的时候,它呢,会有比较比较多的这个东西啊,那其中呢,有一大部分就是什么呢?就是不属于他的东西,但是呢,他需要加载的东西,比如说我EE我用了一个这个API,那么这个API属于谁呢?肯定是属于某一个动态链接库的,那么这个时候它就需要把这个动态链库也加载进来啊,一起来加载,那么他们呢,全被加载到同一个这个进程的这个虚拟空间内了,那么我们的EE呢,它是处于第一个啊第一个啊加载进来的,所以说它其实一般情况下,它是它的地址是位于最前边的,然后呢,我们这个地址啊,我们这个地址和模块的地址,它其实是分开的,我们首先呢,我们要了解啊,我们的这个EE,它首先要有一个base啊base,而它这个base呢。
02:42
它是一个PE文的一个这个字,我们的这个动态链接后实际是个PE,它是个字,我们现在呢,以一个程序为例啊,比如说我把它创建起来,然后呢,我们用呃代码周器就可以看到里边的东西啊,我们点击啊,然后呢,你可以看到这些呢,就是我们的一个呃状态,首先呢,我们correct呢,它在我们的这个em base的位置呢,是374个零啊,然后它em size呢,是后边的这个41000这么一个大小,也就是说呢,从37000开始啊,一直到这个,再加上这个啊D41000啊,这有个D我没看着啊,这个地方结束啊,他们这个之间呢,都是属于credit process的一个进程空间的,然后呢,你可以看到底下这些东西呢,都是什么,都是我们它需要的这个动态链接库啊,你可以看到我们的credit price呢,加载了很多很多的动态链接库,这些动态链接库呢,都是干嘛的,都是在这个我们的虚拟内存空间内的,所以每一个动态链接库呢,实际上都有一个image base。
03:42
后边呢,都有一个size啊,那我们这个不同的base呢,在于我们的这个动态库自己,而实际上就是这个东西就是这个参数,这个参数就相当于我们的加载模块的模块加载的机制啊,也就是我们的image啊,另外呢,这个东西呢,还还叫什么呢,这个东西实际上应该叫做模块具啊,但是实际上而言呢,它就是em image space啊,他们俩本质上是一样的。
04:16
好,那么这是第一个参数,第二个参数呢,是什么呢?你可以看到它在这里呢,用这个第二个参数做一个分发,所以说呢,这个东西呢,它实际上是在告诉你,你是以什么原因触发的啊,以什么原因触发的啊,你比如说如果说你是这个注入到进程里的时候,它会触发一个什么,触发一个啊这个进程的啊,这个这个入侵。或者说进程后的附加啊,那底下这是现成的附加,然后在底下这是现成的这个玻璃啊,这个是进成的玻璃啊,那其实就是四种状况啊,当你附加到进程的时候啊,附加到这个县程的时候啊,退出的时候啊,它都是有各自的事件的,英特尔白皮书完整版本在英特尔官网上下啊,你都叫他英特尔白皮书了,它肯定是在官网上会给你提供的啊,他有一个PDF英特尔白皮书,在早期的时候,他可以申请那个送你实体书啊,但是近五年以来啊,已经不送了啊,你可以下载PDF自己打印啊。
05:21
好,那我们现在呢,就已经知道这些东西之后呢,我们来给它进行一个这个测试啊,我们在这个附加进程的时候呢,给它调用一个这个mabox。嗯,注入动态链接库后,进程内有线程启动,但是注入动态链接库并没有收到这个线程附加的通知啊,知道是怎么回事吗?这个不知道。
06:16
嗯,正常情况下的情况下,你是应该会收到的啊,但是你没有收到的话。嗯。没有收到很奇怪啊,他怎么会收不到呢?应该是启动的时候都会收到的呀。嗯,这个我暂时没想明白啊,如果你有实际上的代码,你可以给我看一下,我这个不太清楚啊,然后呢,我们把它生成之后呢,我们把它打开,打开之后呢,我们把它放到我们的桌面上啊,然后呢,给他先测试一下注入的情况。啊,就在粘错东西了啊,然后我们打开这个进程啊,打开这个进程之后呢,哎,我又打开了一个啊。
07:05
放在这儿,然后点击注入动态链接库啊,把这个动态链接六啊,你看诶失败了啊,失败了是因为我这个代码输入器应该不是以这个管理员这个身份运行的啊,我们给他要以管理员身份运行啊,不然他权限不够啊,确实搞不进去。嗯,猪。嗯。啊,已经弹出来了啊,看这就注入成功了啊,然后呢,我们现在呢,就是把它点确定之后它才返回啊,然后呢,点击确定,确定之后呢,我们这个就完事了,你看它就已经有这个动态库在了啊,这个呢就是一个注入的功能啊,那我们现在呢,先把这个注入的功能呢给它实现出来。啊,我们创建一个新的模块啊。点击新建呃项目,然后呢,我们创建一个控制台吧,我们就不写界面了啊,因为写了也没什么用啊好,做这个DEMO的情况下,我们直接写一个这个控制台应用,然后点击确定。
08:12
好,它给你生成了一个默认的程序啊,然后呢,我们在这个上边来给他操作就行了,首先呢,我们有一个输入输出入流了,我们再给他来一个windows.h就行了,好,然后呢,在退出之前呢,我们给它写一个返回值,在这个位置呢,给它停一下,调用一个system。你刚才说的是无痕hook那种V那种是吗?V那种的情况下,如果说你新的没有收到,说明你什么,你那个循环循环设置那个线程可能有问题,因为微也是我写的时候,我是把它的这个,呃,把它这个每一个这个新启动的线程,我都会重新给他,就是这个进行设置,然后让他也会能响应到啊,你可以去官网上下我那个代码吧,我把代码放在官网那个专题课里了,那个课是可以找老板直接这个免费领的,你直接领完之后在里头就可以直接下源码,你干嘛自己抄啊对不对,你直接下了就行了,好,然后呢,我们现在呢,来实现一个这个注入的一个功能啊。
09:38
好,那我们要注入呢,首先呢,我们要干几件事情啊,首先呢,第一步呢,就是打开进程,第二步呢,是在啊目标进程内申请一段可读可写的空间。
10:06
啊,这段空间呢,是用来这个存储啊,这个加载动态链接链接库的,呃,地址的好,然后呢,第三步就是把这个动态链接库的地址。把动态链接库的地址写入到啊目标内存内。第四步,创建远程线程,把load library。啊,Below the library啊,作为回调函数啊,并且把刚才的地址作为参数进行调用,第五步啊,就是等待远程线程执行结束,第六步清理释放空间。
11:20
巨变。好,这就是完整的一个过程啊,那为什么可以这么做呢?这主要是取决于我们这个函数啊,啊,你看它这个函数,我们直接把它原型拿出来啊,它这个原型在这个位置上,那这个这个东西呢,我们先丢在这儿啊,然后呢,我们来看一个东西就是create process啊,它的它的回调函数的原型啊,不对,Createad啊,我们F12进去啊,你看这是它的函数原型啊,Start这个原型啊,我们这个原型呢,你可以看到其实就是一个函数指针啊,我们把它也出来,出来对比一下啊,那么他们俩这个东西本质上其实是一样的啊,因为什么你看这个是h model啊,这个我们刚才说了动态电库,它实际上就是一个四字节的一个加载模块机制啊,其实就是一个ord,那它这也是一个or,首先返回值一致,然后呢,我们这个名字啊,其实无所谓啊,那么这个啊,你看vpstd call啊,它这个调用约定一致,然后呢,它的参数一个lp word,一个LPCWSTR,这个是一个字符串,这个是一。
12:22
空间本质上都是一块连续的内存啊,也就说参数意识,也就说这两函数基本上就是一模一样的两个函数,所以说呢,我们把这个啊,Load library啊作为create create three的一个回调函数是完全没有任何问题的啊,那所以说呢,我们可以直接的去使用它,那么首先呢,我们第一步分来打开进程啊,那就是一个handle h price的一个接收,等于open process。然后给它传传一个这个打开的一个权限啊,就是一个process or啊or的一个返问权限,然后是否继承返回的句柄啊,那我们就要不要让它返,呃,不让的继承就可以了,最后呢,是一个进程的ID啊,我们在参数里啊拿到啊DWPID,好,这就是第一步打开进程,然后第二步啊,申请一个可读可写的空间啊,那我们用一个RP word啊来接收它返回的这个空间的指针。
13:37
等于啊,我们使用v ILO克ex啊进行进行申请ILO克ex啊不带exs版本,是本进程的申请啊,如果带了ex是跨进程的一个申请啊,然后呢,我们现在呢来使用它啊H第一个啊进程的一个柄,第二个传一个,第三个申请的一个长度,第四个啊内存的一个属性。
14:05
然后再下一个啊,是叶的一个保护属性这记页啊,然后呢是red啊读写好这就申请完了,申请完之后呢,把我们的动态用户的地址给写到目标进程里去啊,那我们首先呢,需要一个返回d word DW g th等于零,然后Y。Memory好,然后写入第一个进程句柄,第二个啊,写到哪里去啊,我们用一个LP,刚才申请的LP和address进行写入,第三个呢,是我们的一个写到哪啊,不是这个路径啊,那路径呢,我们从外边传进来的啊,直接使用参数,第四个啊,路径的一个宽度啊,那我们计算一下WCS。
15:14
加一乘以二。好,然后呢,是我们的返回啊,实际上写了多长啊,那用它来接收一下就可以了。好,然后创建远程线程啊,网络library作为一个回调函数啊来进行调用,那我们本地用的呢,是这个创建线程啊,我们远程呢,就用一个创建远程线程就可以了。第一个还是进程聚柄啊,然后第二个呃安全呃线程属性啊,我们传个道,然后第三个啊嗯嗯,第三个啊,我没写到第三个啊,第三个啊占尺寸啊,然后一个闹。
16:10
然后是再下一个啊函数启动地址,这个呢,我们使用这个load library load library,我们用一个load library w。然后它类型会不符啊,我们F12跟进去使用它第三个的函数帧类型,对它进行类型相转好,然后呢,第四个是它的一个参数啊,那参数呢,我们在刚才已经申请过内存,并且把这个路径写进去了啊,我们就直接在这调用,然后第五个啊是一个创建flag啊,那这个东西呢,我们不需要啊,那就闹啊,然后再有一个是线程ID不需要闹好这样就OK啊给给创建好了,然后接下来等待啊,那我们就是这个white for single object啊来进行等待,等待着我们的h threead进行返回啊,我们I负一啊,永久等待啊,然后呢,最后清理啊,这个释放,那首先清理啊,那就是我们调用这个VV车free ex进行清理,首先啊清理的这个进程句柄,第二个啊清理的空间LP。
17:21
Address。A DD re ss,好,然后呢,再下一个是它的一个长度。啊,长度这个release的话,我们直接传个零就行了啊,不需要计算啊,我想起来了,然后呢,下一个呢,就是它的这个属这个清理的属性啊,我们用这个MEM release啊,这个需要特殊说一下啊,它这个release啊,在这个MSDN上有一个特殊说明,如果你要使用它的话,你的尺寸就直接写个零就可以了,好,这就是清理空间,然后呢,我们释放句柄,Close handle,首先两个东西需要释放,一个是我们的进程句柄。
18:01
一个呢,是我们的线程句柄,好,这就写完了,写完之后呢,我们来这儿啊,对它呢,进行一个调用啊,然后呢,比如说我现在先启动一个。呃,启动一个进程。任务管理器啊,然后是详情。22072。然后是路径啊,我们要注入的是这个。
19:12
好,然后呢,我们现在呢,来运行它啊,来对它进行一个注入。嗯,启用了缓解库啊,没有关闭啊,然后属性C加加代码生成啊MTD,然后缓解库关闭啊,应用确定来运行。走。可以看到已经注入成功了啊,说明我们注入了代码是没有问题的,那么这个呢,就是我们注入部分好输入部分之后呢,我们现在呢,再来给他,呃,写一下这个hook啊,什么叫hook呢?比如说我现在第一个我正常情况下也弹出的是test啊,第二个啊来再运行还是test再运行啊,然后走它就没了,那我现在呢,想把它上面的文字给改掉啊,那我是应该怎么样去拦截它的这个函数啊,然后把它直接上面显示的参数给改掉就可以了,那么我们要实现这个东西呢,有很多种方式啊,像咱们的这个有专门的专题课可以领取啊,那现在呢,我就给大家演示一个其中比较基础的一款,就是直接使用这个音赖啊内联获的方式啊,对其进行修改。
20:27
好,我们创建一个啊,不用创建项目了啊,我们刚才写了一个这个动态链接库啊,我们直接在这上边写就行了啊,然后呢,我们现在呢,需要三个函数啊,以及我们要包含一个头文件啊,在这儿包含一下我们的这个windows.h头文件。好,然后呢,我们在这儿啊,然后要给它创建三个参数啊,首先PC啊,一个函数fun a drs啊这个呢是什么呢?这个其实就是我们这个要hook要hook函数的函数地址啊然后。
21:10
1TM。Old betters这个东西呢,是要hook函数的头五个字节保存,然后再来一个m news5这个是什么呢?这个是啊新的啊要替换,要替换到啊,目标函数头五个字节的啊,心字节啊,它的这个想要形成的是什么呢?是一个占啊,然后12345678这种的一个东西,相当于什么呢?相当于啊里边是一个一九啊,然后啊,叉叉叉叉叉叉叉叉叉这样的一个地址啊好,那我们现在呢,就来干嘛呢,来了解一下它的一个原理啊,那首先比如说我这个东西,我来拖到我的这个条。
22:15
器上。啊,没点关注的点点关注啊,我们每周六周日晚上八点都有直播啊,然后有需要往期课程或者说免费课程的,可以找咱们的老板进行领取啊好,然后我直接F9走到自己的领空上,然后呢,我们现在搜索啊当啊搜索当前模块,呃,跨模块调用呃,你看这有两个啊,然后比如说我们先给它点进来一个啊,应该都在附近,你看在这儿啊,那我们这有一个ma boxx a啊,它就是弹出那个用的啊,上面是它的两个参数啊,那我们现在呢,想要它啊,那怎么呢?比如说我现在点击进来之后,你可以看到它这个上边呢,是这个这个整个的,其实就是它的一个这个实实现啊,那我们现在想要的实际上就是把它前边的五个字节给它替换掉,替换成什么呢?换成我刚才说的一个地址啊,首先你比如说它现在前面五个字节是什么,是这么多,然后是8BF558BC,那我现在首先第一个8B替换成一九,那后边这四个字节呢,就可以直接替换成一个地址,然后当一个函。
23:18
数执行到它调用它的时候,到他这儿了,就直接它会跳到我们自己的函数内啊,进行一个执行啊,如果说他要在回来的时候,我们再把原来的五个字节给它替换回来啊,让他我们自己再调用它一下,它就回来了啊OOK呢,其实就是这么一个原理啊,就是依赖就是这么一个原理啊,那我们现在呢,就来实现这么一个这个功能。首先呢,我们需要一个这个hook函数啊,一个布尔的一个返回值,一个H差星啊,P z name模块名啊,然后是constant差星啊,然后PSZ啊,F nc name这是要的名啊,然后第三个PC啊,然后啊,PFN这个是我们自己写的啊,要持过去的函数,那个函数的地址好,然后呢,现在我们开始来给进行实现,首先呢,我们在指定的模块中获取指定模块的一个地址啊,就把要这个函数的地址拿到啊,那我们直接存入到我们这个变量中啊,那它等于什么呢?等于我们调用一下get get proc啊呃,Proc address,然后它两个参数,第一个是模块句柄,第二个是一个函数名,那第一个这个。
24:40
他说模块句柄呢,我们使用这个get handle a。啊,就可以直接来获取,比如说我们这个东西它在那啊,那在我们这个模块的里边啊,我们第一个有模块名这个参数,然后第二个呢,是函数名,我们也直接传进来一获取就行了,获取到函数地址之后呢,我们可以判断一下这个函数地址是不是为now,如果为now的情况下呢,说明没有拿到它啊,那么这种情况下我们就直接一个false,好,如果说拿到了的情况下,我们把它头五个字节啊,我们给它保存起来啊,那保存起来呢,就是什么方法呢?我们就直接通过read啊来直接去读,读取这个函数的前五字节啊,把它读回来啊,Read啊,Read process memory,然后进行读取,首先啊,我们获取一下当前进程,因为我们已经注入进来了,实际上就是当前进程啊,我们拿到一个当前进程的一个句柄,拿到这个句柄之后,第二个就是你要这个读的位置啊,那我们把这个地址传进去,第三个你要读的这个位置。
25:45
后存到哪儿啊,我们存到这个old bes里啊,然后呢,再结后,接下来就是读几个几个字节啊,我们会读五个字节,再接下来呢,我们就是啊,要返回实际上读取的个数啊,那就是DW return啊,写错字了,Re r了,Return,好好这样就可以了啊读完之后呢,我们现在呢,就可以构造这个新的指令了,我们刚才说了啊占构造成这样的指令啊,首先第一个字节是一个一九啊,那我们就直接把这个new beats啊,它的第零个字节啊,给它设置成啊一个一九。
26:22
然后呢,我们后边呢,正好还有四个字节嘛,就可以当做一个dord来赋值,直接把它剩下的那部分给它这个写进去啊,那我们直接把它啊加一啊,这样呢,形成一个新的地址啊,在它这个一的位置上,往后正好是一个ord,那么这个时候呢,我们可以把它强行啊强行转换成一个dord,然后再截引用啊解引用是为了往里写值啊写值现在呢,我们这个计算方法呢,就是我们使用我们的这个呃,目标的这个函数地址减去啊我们的当前的函数地址,然后再减去指令长度啊,指令长度呢,现在指令长度是个五,那我们减五,如果是七就减七啊啊,然后这样计算完事之后,这得到的是一个相对地值。
27:07
好给他写完了,写完之后,嗯,我看一下啊,这有一个错误啊。表达式类型必须是完整的纸质类型哦。啊,这个是ord啊,这个是什么?这个啊,这个应该是ord,不应该是KROC啊啊这就对了,好,然后呢,我们就把这个五个字节啊给它写过去啊,然后we memory啊,然后接下来我们还是获取一下当前的句柄。在接下来呢,我们就是要写到哪里去,然后再接下来呢,就是我们要写的是什么东西。再接下来啊,五个字节,再接下来啊,返回。好都搞定之后呢,我们直接啊RETURN1个数,这里头呢,其实还有地方需要这个进行进行判断啊,比如说你外的process和这个process有没有成功啊,应该做一个布来进行判断一下,但因为我比较懒,我就没有判断啊,就这么着了,好,然后呢,我们进行一个卸载on hook啊on hook呢,其实就把原来的几个字节给它替换回去啊,如果说啊,我们的这个函数地址啊,嗯,我给它写一下啊,函数地址,函数地址不等于零的情况下,那就说明啊这个东西已经被H了,那么我们就直接啊给它进行一个外。
28:38
外什么呢?就是把它的这个老的五个字节啊,给他写回去就行了,这样就是还原了嘛,把户还原回去了,好,然后呢,我们还需要一个重新户口啊。啊,其实也一样,就把那新的五个字节再给他替换回去吧。
29:06
好,这就OK了,OK之后呢,我们现在呢,要来护谁啊,那我们就把它这个给它写出来,嗯,比如说我们现在呢,要呼这个。呃,Ma boss啊,刚才弹出来的ma bos,那我现在呢,就来找一下ma bos的一个原型。哦,比如说是这个啊,那我把它拿出来。然后呢,现在呢,我把它这个东西呢,给它改一下这个名字啊,比如说改成这个my my Bo,然后呢,给它把分号去掉,写一个实现,实现呢,我现在呢,在这个位置上呢,只说一件事,就是首先呢,我把它on hook啊,然后替换掉,把它这个把它卸掉啊,卸掉之后呢,在临走之前,我再给它hook回来。啊,再调用一遍。
30:10
好,然后呢,我们,哎,我们就可以调用它的原过程了,直接调用一个Bo a,好然后呢,现在呢,我们有几个参数啊,首先第一个串口句柄,我们直接原模样给它放回去啊,然后这个文本呢,因为我们想要替换它,所以说呢,我们就给它替换成一个新的。啊,这个第四个参数我们也用原来的啊,给它把它替换回去好,然后在这呢,给它接收一下,接收一下它的返回值啊int itt等于啊,然后我们返回的时候,把它的这个返回值给返回回去。好,现在就OK了,OK之后呢,我们现在呢,就来去调用它一下啊嗯,我们在这个加入的时候,我们给他调用一下,调用的时候呢,我们首先呢,做一个初始化fun。
31:09
嗯,Address啊,给它设置成这个now,然后呢,Memory set,把我们的两个字符串都给它设置成这个零。IOLD0啊,然后是五个字节,然后是memory set I'new betters05个字节,好,然后呢,在联系后呢,就我们进行一个调用hook,然后呢,我们这个UU这个ma bos呢,它是在我们的u332.d里啊,所以说我们直接传接下来就是我们的这个函数名啊,那我们直接把它复制过来。再然后呢,就是我们新函数的一个函数地址啊,那我把新函数的地址换过来啊,但是呢,需要类型强转,把它强转成这个PC。
32:06
好,然后呢,转成PC之后,这就OK了,OK之后呢,在临走之前我们进行一次on就可以了。啊,如果你觉得你恢复的一瞬间访问的这个过多会漏掉的话,你可以使用热补丁的这种方式啊,热补丁它就不会漏啊,热补丁的你是使用的是原地址加二的方式啊,也就是它护OOK的时候是短片啊,如果你想知道热补丁是怎么hook的,也可以去领一下那个hook专题啊,热补丁它就不会漏东西,好然后呢,我们现在呢,给它重新生成,嗯,户必须返回一个值啊,那我返回一个数好了啊,然后重新生成。然后我们打开打开打开诶点错了,打开诶点错了,我操手有点瓢。当天就库啊,然后把它粘贴替换替换。
33:05
好,现在呢,我把这个东西给它打开。现在你看它是T啊,然后呢,我打开任务管理器,找到它的这个。我操他,他的进程名是什么东西?找一下开头的啊,这呢是21928。好,这个运行。好,这应该是注入完了啊,注入完之后点击确定,然后再走。回车回车,诶。哎呀,点快点没了,那重新来一下。23944。
34:16
看已经hook成功了啊,这就是hook啊,今天呢就讲了两种比较基准的方式啊,一种叫远程线程注入,一种叫做赖hook啊,都是我们在注入和中啊,最简单的,但是也是必须掌握的两种啊好,那现在呢,我们这个东西就OK了啊,如果有问题现在可以在面上啊来的啊。
我来说两句