首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

2.5 CE修改器:寻找数值指针

上一步阐述了如何使用代码替换功能对付变化位置数据地址,但这种方法往往不能达到预期效果,所以我们需要学习如何利用指针,在本关Tutorial.exe窗口下面有两个按钮,一个会改变数值,另一个不但能改变数值而且还会改变数值在内存中存储位置...接下来我们将找到内存中基址,为什么要找指针,在前面的教程中,如果各位细心观察的话就会发现 在笔者截图中出现地址和你地址并不相同。...也就是说,这些地址是一直在变化,我们把它叫做动态地址,我们必须寻找到该动态地址基址,并以此来保证唯一性。...;至此读者通过双击打开mov [edx],eax则可看到当前汇编指令详细输出情况,寄存器EDX后面并没有任何偏移地址,此时读者只需要关注EDX寄存器,因为该保存有指向下一个区域内存地址,将地址...01A252A8复制到剪辑版中;将新地址以十六进制格式搜索四字节,并可输出一个绿色"Tutorial-i386.exe"+2566B0没错,该地址就是一个基地址,此地址在程序重启后也不会发生任何变化

59450

2.5 CE修改器:寻找数值指针

上一步阐述了如何使用代码替换功能对付变化位置数据地址,但这种方法往往不能达到预期效果,所以我们需要学习如何利用指针,在本关Tutorial.exe窗口下面有两个按钮,一个会改变数值,另一个不但能改变数值而且还会改变数值在内存中存储位置...接下来我们将找到内存中基址,为什么要找指针,在前面的教程中,如果各位细心观察的话就会发现 在笔者截图中出现地址和你地址并不相同。...也就是说,这些地址是一直在变化,我们把它叫做动态地址,我们必须寻找到该动态地址基址,并以此来保证唯一性。...; 至此读者通过双击打开mov [edx],eax则可看到当前汇编指令详细输出情况,寄存器EDX后面并没有任何偏移地址,此时读者只需要关注EDX寄存器,因为该保存有指向下一个区域内存地址,将地址...01A252A8复制到剪辑版中; 将新地址以十六进制格式搜索四字节,并可输出一个绿色"Tutorial-i386.exe"+2566B0没错,该地址就是一个基地址,此地址在程序重启后也不会发生任何变化

51650
您找到你想要的搜索结果了吗?
是的
没有找到

植物大战僵尸:学会使用人造指针

2.上图可以看到有两条汇编指令,而前面的计数器一直在增加,说明有时钟一直在访问这个地址,我们以第2条汇编指令为例,点击反汇编当前地址在XOR指令上按下F5下断点,其中mov eax,[esi+5560]...则表示将当前阳光数量赋值给EAX寄存器,我们可以看到右侧寄存器窗口eax=32,其中32正好就是阳光十六进制表示形式,注意mov eax,[esi+5560]这条指令,观察该指令在注入前与注入后会有什么变化...originalcode之前写入以下汇编代码,其中push eax,pop eax分别是压栈与出栈,因为我们要使用EAX寄存器暂存数据,此时必须要将原始EAX寄存器里面的内容进行保存,在代码执行完毕以后必须通过...POP指令归位,否则会导致程序异常或堆栈失衡,mov eax,[esi+5560]则表示将[esi+5560]中数据取出来,此处就是阳光数量。...,并且类型为映像,这里还需要看后面的模块一定要是植物大战僵尸文件里模块,此处找到了一个内存地址 0B4CF000,双击即可跳转到相应位置,这里我们不能选择02CA9000这个内存地址,因为这个地址是

45620

植物大战僵尸:辅助制作高级技巧

2.上图可以看到有两条汇编指令,而前面的计数器一直在增加,说明有时钟一直在访问这个地址,我们以第2条汇编指令为例,点击【反汇编当前地址】在XOR指令上按下【F5】下断点,其中【mov eax,[esi+...5560]】则表示将当前阳光数量赋值给EAX寄存器,我们可以看到右侧寄存器窗口【eax=32】,其中32正好就是阳光十六进制表示形式,注意【mov eax,[esi+5560]】这条指令,观察该指令在注入前与注入后会有什么变化...,此时可以在【originalcode】之前写入以下汇编代码,其中【push eax,pop eax】分别是压栈与出栈,因为我们要使用EAX寄存器暂存数据,此时必须要将原始EAX寄存器里面的内容进行保存...8.此时我们通过代码注入器,向程序中注入代码,即可实现产出阳光,到此还没有结束,下方注入代码有一个变量【13DBD880】这个动态内存地址每次启动游戏都会发生变化。...6.最后附一张注入成功后效果图,如下所示: 通过手工计算偏移地址 首先我们思考一个问题,为什么我们需要手工计算偏移地址,CE找不开心吗?

86820

__asm__ volatile 之 C语言嵌入式汇编

这次,GCC老老实实将if语句生成了汇编代码。 可能有人会质疑:为什么要使用__asm__("":::"memory")向GCC声明内存发生了变化?...但我们以后例子会更加清楚表现这一点。 关于为什么内联汇编__asm__("":::"memory")是一条声明内存改变语句,我们后面会详细讨论。...如果你用了它,则是向GCC声明“不要动所写Instruction List,需要原封不动保留每一条指令”,否则当你使用了优化选项(-O)进行编译时,GCC将会根据自己判断决定是否将这个内联汇编表达式中指令优化掉...括号括住部分是一个C/C++表达式,用来保存内联汇编一个输出,其操作就等于C/C++相等赋值cr0 = output_value,因此,括号中输出表达式只能是C/C++表达式,也就是说它只能是一个可以合法放在...,或使用"g","r"等约束让GCC为其选择寄存器,GCC已经知道哪个寄存器内容发生了变化,所以这么做没有什么意义;也作了相关试验,没有发现使用它会对GCC生成汇编代码有任何影响,至少在i386平台上是这样

12K44

Linux内核33-信号量

相反,如果信号量等于0,该进程就会等待,直到有其它程序释放该信号量。释放信号量过程就称为V操作,通过增加信号量,唤醒正在等待进程。 注: 信号量,这一同步机制为什么称为PV操作。...当然了,结构体变化必然导致操作信号量函数发生设计上改变。 3 如何获取和释放信号量 前面我们已经知道,信号量实现在内核发展过程中发生了更变。所以,其获取和释放信号量过程必然也有了改变。...如果eax寄存器大于0,说明没有进程在等待这个信号,则跳转到标号1处开始执行。...使用加载有效地址指令lea将寄存器ecx中地址加载到eax寄存器中,也就是说把变量sem->count地址(因为count是第一个成员,所以其地址就是sem变量地址)加载到eax寄存器中。...至于两个pushl指令把edx和ecx压栈,是为了保存当前。因为后面调用__up()函数时候约定使用3个寄存器eax,edx和ecx)传递参数,虽然此处只有一个参数。

1.4K20

linux内核学习(四)之回顾简单汇编知识(一))

$0, %eax 好了,这里也只是感受一下,具体Intel(X86-64)汇编风格,后面会在c语言专辑里面详细写到(结合我们平时c语言程序类具体分析!)...那么为什么CPU在运行时候要有寄存器这么东西呢,之前看过一段话,解释比较到位: 想象CPU是一个圈一直在运转,然后寄存器里面有大量指令,这些指令不知道从哪里来,但是一般情况下我们CPU在计算我们程序...,内存并不稳定并且很慢,所以就要想办法能不能找到一个临时空间保存一下,这就是为什么会诞生寄存器。...CPSR和SPSR都是程序状态寄存器,其中SPSR是用来保存中断前CPSR中,以便在中断返回之后恢复处理器程序状态;CPSR是当前程序状态寄存器意思,SPSR是程序状态保存寄存器,这里在网上看到一个非常通俗易通解释这两个寄存器用法...,但是这个时候当时状态已经被清理掉了,这个时候我们就可以用SPSR把原来那个状态保存,这样当状态在发生改变时候,要还原就可以去SPSR里面读取之前那个状态,这就是它们之间关系,就类似有一个A变量

47410

盘点.NET JIT在Release下由循环体优化所产生不确定性Bug

L0003: mov eax, 1 L0008: inc eax L0009: cmp eax, 0xa Release较Debug变化是:JIT知道在当前方法上下文中,len是个局部变量,且始终不会改变...因此,在往后对循环体编程中,若代码主体不会改变循环变量的话,那么尽量可以在循环体中创建一个副本来去使用,这样对性能可以有效提升。...介绍完通过将循环变量直接存储在寄存器方式所带来性能提升后,下面将介绍因为这种jit优化方式所带来潜在性Bug。...第二条线程将改变i以让它小于等于0 按照正常逻辑来走,第二条线程一定会执行改变代码,因此方法在运行后始终会终止(会因主线程跳出循环结束而结束)....在第二段中,已经举例介绍了这种优化,这取决于JIT是否能跟踪到代码对变量i更改,若JIT通过中间形式解析后能够跟踪到对循环变量修改,则对循环变量将不会使用寄存器来进行优化。

60920

通过实例学习ROP技术

但是在任务管理器里面始终找不到 QQpinyin 进程,可能是程序加载了 QQPinYin 模块,而这个模块一直在循环 ReadFile (这难道是键盘记录嘛,不懂不懂,求大佬赐教)。...这里选择寄存器,因为如果存在栈中的话你需要不断改变 esp mov [esp],某个寄存器 并且不断调用这样语句对栈内容进行赋值,操作简单但是过于繁琐。...把该地址放在 ROP 链首端,也就是把 0022FD54 覆盖为 649b11ec(具体怎么覆盖,大家可以自行计算),顺便手动把 OD 中这几个寄存器改变一下(esp 不能动)如图: ?...pop esi,我们可以随便给 esi 弹一个就行了 计算第二个参数 dwSize(EDX) 想法是让 eax 做运算,最后把 eax 赋给 edx。...计算第三个参数(ECX) 我们需要把 ecx 变为 00000040,在这个参数上思考了好久,一直没有找到解决方法,本来是这么打算 xor eax,eax add eax,8 add eax,

73400

系统调用(int 0x80)详解

Int 0x80输入输出参数说明: 输入参数:eax=功能号(比如2为fork系统调用) 用功能对应sys_call_table[]下标,比如sys_call_table[2]表示fork系统调用函数...fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, 返回EAX=sys_fork函数返回...为什么不能保存到用户态堆栈,如果保存了用户态堆栈,那么,这些栈内存区域,用户程序就可以必改定,那么,程序就很容易被攻击了,直接修改CS:EIP对应栈内存,那么,你懂^_^。...//系统调用函数返回入栈 关于进程状态变化,参考书上说明,这部分,理解还不够,后续再分析???...所以,当从系统调用相关功能号对应函数返回时,需要检查当前进程是否还在就绪态,或时间片是否用完,并确认是否需要重新执行调度程序

1.3K40

利用ESP定律upx脱壳实践

,紧跟在popad后第一个JMP指令可跳转到OEP 实践: 1:查壳 2:OD打开 3:F8 //对于寄存器,指令执行后发生改变寄存器会用红色显示,此处ESP和EIP发生改变...,因为执行pushad指令,将8个通用寄存器EAX-EDI)保存至栈,栈中增加了,所以ESP发生变化,而EIP表示下一个要执行指令地址,也发生变化 (执行PUSHAD原因是使栈平衡...,这段代码最后还有popad,两者执行后可以把ESP回到原值,这里不明白为什么使栈帧平衡要执行push和pop,如果没有这两步只执行movebp,esp,不是还有基准,搞不懂push和pop意义...ESP为000DFF54时,下一个命令是popad (popad指令把pushad存储在栈中再次恢复到各个寄存器理解为8次pop命令) 5:F9运行 //猜测未执行popad时,ESP...//发现OEP处寄存器除了EAX和EIP,其他和pushad一样 EAX中值不一样原因是,EAX中保存函数返回,保存是OEP地址 7:脱壳 总结: 1:

87220

C语言:底层剖析——函数栈帧创建和销毁

3、函数调用时形参是如何传递,传递和调用顺序又是怎样? 4、为什么说形参是实参一份临时拷贝,改变形参不会影响实参? 5、函数返回是如何带回去?...相关汇编命令: mov:数据转移指令 push:数据入栈,同时esp栈顶寄存器也要发生改变 pop:数据弹出至指定位置,同时esp栈顶寄存器也要发生改变 sub:减法命令 add:加法命令 call:...程序是在函数调用返回之后,在eax中去读取返回。...中 mov         eax,dword ptr [ebp-8]       将ebp-8地址处放在eax中,其实就是 把z存储到eax寄存器中,这里是想通过eax寄存器带回计算结果,...传参顺序是从右到左,调用顺序是从左到右。 5.4 为什么说形参是实参一份临时拷贝,改变形参不会影响实参?

24110

红队 | InlineHook技术实现

IAT表中无法找到,InlineHook算是对IATHOOK一个升级版吧 大体思路 用JMP改变函数入口,JMP到我们自己函数,然后又JMP回去执行刚刚没执行完函数。...过程无论怎么变,一定要让堆栈平衡和保留原来寄存器,这是Hook是否成功关键....,后面我们要还原现场.这里先创建了一个结构体用于接收寄存器,等会方便打印 typedef struct _regeist { DWORD EAX; DWORD EBX; DWORD ECX; DWORD...这里找到一篇文章说明为什么有这种机制: https://blog.csdn.net/x_iya/article/details/13161937 测试结果 ?...调用了两次函数,但只有一次输出说明卸载也成功了 完整代码 // InlineHook.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

55340

【内功修炼】深入理解函数栈帧创建和销毁

但不能用于直接从内存复制到内存 push:数据入栈,同时esp栈顶寄存器也要发生改变 pop:数据弹出至指定位置,同时esp栈顶寄存器也要发生改变 sub:用于两个操作数相减,相减结果保存到第一个操作数中...当然我们还可以通过内存窗口看一下它是否真的压进去了: 因为现在esp指向空间里前4个字节放到就是ebp 没问题。...esp里面的发生了变化,并且我们上面pusheax上面好像又多push进去了一个 而且我们会发现新push进去这个就是前面call 00EA10B4这条指令下一条指令地址。...是最终结果z。 所以它又把Z放到了eax寄存器里面。 那大家思考一下,为什么不直接返回z呢?为什么要要把结果放到寄存器eax里面呢?...程序是在函数调用返回之后,在eax中去读取返回。 那再往下,是printf函数调用,接着就是main函数栈帧销毁,那它们和Add函数调用以及栈帧销毁是差不多就不过多赘述了。

15211

操作系统(4)实验0——准备知识、基本内联汇编、扩展内联汇编

; 我们可以看到,这几句已经改变了ebx和edx,但是因为他是事先“打印”成文件再交给GAS进行汇编,所以GAS不会知道已经这些寄存器内容已经发生改变,仍然会假设寄存器内容是合法。...然后clobbers部分告诉GCC寄存器ecx和edi内容可能已经被改变了。...*/ ); 这个代码实现功能就是将a赋值给b,注意对应输入输出部分是怎么写。...然后是输出部分,输出部分是必须有=,=r代表目标操作数可以使用任何一个通用寄存器,并且变量b存放在这个寄存器中(或者这么说,这个寄存器与变量b相关联,先将操作数读入寄存器,用这个寄存器执行相应指令...最后clobber部分表示汇编代码会改变eax寄存器内容,这样gcc在调用内联汇编时候就不会直接假设寄存器eax中内容合法并直接使用。执行完这段代码之后变量b就会被改写。

69520

C语言再学习 — 关键字volatile

翻译: 表示一个变量也许会被后台程序改变,关键字 volatile 是与 const 绝对对立。...我们知道 volatile 和 const 一样为类型修饰符,不改变变量类型。 寄存器地址为什么要加 volatile 修饰呢? 是因为,这些寄存器里面的是随时变化。...3、多线程应用中被几个任务共享变量 当两个线程都要用到某一个变量且该变量会被改变时,应该用 volatile 声明,该关键字作用是防止优化编译器把变量从内存装入CPU寄存器中。...,寄存器中bStop永远不会变成FALSE,加上volatile,程序在执行时,每次均从内存中读出bStop,就不会死循环了。...如 果没有 volatile 关键字,则编译器可能优化读取和存储,可能暂时使用寄存器,如果这个变量由别的程序更新了的话,将出现不一致现象。

30600

程序员内功心法之函数栈帧创建和销毁

局部变量是如何创建为什么局部变量不初始化其内容是随机? 有些时候屏幕上输出"烫烫烫"是怎么来? 函数调用时参数时如何传递?传参顺序是怎样? 函数形参和实参关系是什么?...---- 2、相关寄存器 eax:通用寄存器,保留临时数据,常用于返回。 ebx:通用寄存器,保留临时数据。 ebp:栈底寄存器,用来记录栈底地址。 esp:栈顶寄存器,用来记录栈顶地址。...,本次函数返回是由eax寄存器带回来。...程序是在函数调用返回之后,在eax中去读取返回。 ---- 7、对开篇问题解答 当我们完整了解了函数栈帧创建和销毁过程后,我们就可以回答开篇提到问题了: 局部变量是如何创建?...函数返回通过eax寄存器带回。 函数是怎样在栈区上开辟和释放空间

42200

函数栈帧创建和销毁

一、寄存器eax,ebx,ecx,edx,ebp,esp.而本文中重点提到是esp和ebp! ebp和esp这2个寄存器中存放是地址,这两个地址是用来维护函数栈帧。...此时此刻,esp也要跟着变化变化成了ebp变化前:  变化后: 接下来,便是move:  ,意思是把esp给ebp,这意味着,ebp不再指向下面那个位置,而是指向esp现在所指位置...其实很简单,看下面的指令:把ebp-8放到eax里面去,eax可是个寄存器啊,因此是不会因为程序退出而销毁!  ...紧接着,把eax放到ebp-20h中去,也就是c地址 最后,打印,然后结束程序,销毁main函数栈帧。 因此:  ①局部变量是如何创建? 给函数创建栈帧,再在空间里面分配变量空间。...也就是说,是通过寄存器带回来! PS:本人对函数栈帧创建和销毁拙见,请有大佬看到其中不妥问题时候,可以纠正问题。谢谢!

74200

C语言——F函数栈帧创建和销毁

2、认识相关寄存器和汇编指令 相关寄存器 eax:通用寄存器,保留临时数据,常用于返回 ebx:通用寄存器,保留临时数据 ebp:栈底寄存器 esp:栈顶寄存器 eip:指令寄存器,保存当前指令下一条指令地址...相关汇编命令 mov:数据转移指令 push:数据入栈,同时esp栈顶寄存器也要发生改变 pop:数据弹出至指定位置,同时esp栈顶寄存器也要发生改变 sub:减法命令 add:加法命令 call:函数调用...; for(; ecx = 0; --ecx,edi+=4) { *(int*)edi = eax; } 之所以上面的程序输出“烫”这么一个奇怪字,是因为main函数调用时,在栈区开辟空间其中每一个字节都被初始化为...8] //将ebp-8地址处放在eax中 //其实就是把z存储到eax寄存器中,这里是想通过eax寄存器带回计算结果,做函数返回。...答:形参是在栈帧空间中创建独立空间,与实参相比值相同、空间相互独立,所以形参改变实参不会发生变化,因此说形参是实参一份临时拷贝。 5、函数返回是如何带回

8310

扫码

添加站长 进交流群

领取专属 10元无门槛券

手把手带您无忧上云

扫码加入开发者社群

相关资讯

热门标签

活动推荐

    运营活动

    活动名称
    广告关闭
    领券