<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[小喇叭儿滴滴的吹]]></title><description><![CDATA[————  安安静静的做一名代码观察师  ^_^]]></description><link>https://blog.youkuaiyun.com/Wang_1997</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; Wang_1997]]></copyright><item><title><![CDATA[csdn博客转markdown]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/128750716</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/128750716</guid><author>Wang_1997</author><pubDate>Sat, 18 Mar 2023 15:21:18 +0800</pubDate><description><![CDATA[近期完成了csdn上的部分博客转到个人博客上，csdn使用的传统编辑器，个人博客使用的markdown，所以下面分享一下两者之间转化。]]></description><category></category></item><item><title><![CDATA[ARM汇编基础下]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/106744811</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/106744811</guid><author>Wang_1997</author><pubDate>Mon, 12 Apr 2021 09:25:16 +0800</pubDate><description><![CDATA[这一篇主要就总结一下ARM汇编中一些指令相关的知识点，指令相关的东西还是挺多的，所以只能挑一些重点来记录。在上一篇中有说指令集相关的内容，这里的话主要是讨论arm指令集，也就是4字节的。

首先，先来看一下指令的一般编码格式，固定占用四字节



对于上图的符号以及参数说明如下：


opcode : 指令操作符编码
cond   : 指令执行的条件编码
S      : 决定指令的操作是否影响CPSR的值(是否影响标志寄存器)
Rd     : 目标寄存器编码
Rn     : 包含第1个操作数的寄存器编]]></description><category></category></item><item><title><![CDATA[ARM汇编基础上]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/106731040</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/106731040</guid><author>Wang_1997</author><pubDate>Sun, 09 Aug 2020 13:24:41 +0800</pubDate><description><![CDATA[ARM是一个精简指令集处理器，其指令集的设计是定长的，也就是其汇编对应的机器码是定长的（2字节或者4字节）。那么对于定长而言，其优点就是更快的被执行，因为这样CPU取指令译码的速度相对x86的CPU会快一些，但是缺点也比较明显，毕竟定长，那么表示其指令有限（指令少），所以一定程度上会软件的复杂度（需要几条指令才能完成一个功能）。

ARM的指令集一开始设计定长都是2字节的，随着时间的发展，会发现指令可能已经不够表达了，所以后面又出现了4字节的指令集。对于2字节的指令集称为thumb指令集，而4字节的称为ar]]></description><category></category></item><item><title><![CDATA[ARM逆向-表达式求值]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/106893168</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/106893168</guid><author>Wang_1997</author><pubDate>Tue, 14 Jul 2020 21:09:24 +0800</pubDate><description><![CDATA[表达式求值也就是把各类加减乘除的运算都看一遍，这里主要记录的是Release版中的一些优化，各种优化手段我感觉有x86的逆向基础还是会比较好理解的，因为很多都很类似。

首先看一下加减的运算，这里主要可能会出现常量折叠和常量传播等优化手段


int main(int argc,char* argv[])
{
    int n1 = argc;
    int n2 = 0;
    scanf("%d", &amp;n2);
    n1 = n1 - 100;
    n1 = n1 + 5 - n2]]></description><category></category></item><item><title><![CDATA[C++ 虚继承]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/105458833</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/105458833</guid><author>Wang_1997</author><pubDate>Mon, 06 Jul 2020 22:35:02 +0800</pubDate><description><![CDATA[对于虚继承而言，是用于解决其在多重继承时出现的二义性问题，所以首先我们先来看看多重继承时会出现的问题


//家具类
class CFurniture
{
public:
    CFurniture()
    {
        m_nPrice = 0;
    }
    virtual ~CFurniture()
    {
        printf("virtual ~CFurni...]]></description><category></category></item><item><title><![CDATA[逆向-字符串]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/105190665</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/105190665</guid><author>Wang_1997</author><pubDate>Mon, 29 Jun 2020 13:59:38 +0800</pubDate><description><![CDATA[在C语言中，字符串其实就是一个特殊的数组，一个以零结尾的字符数组而已，所以对于定位字符串中的字符的话可以参考上一篇博客-数组。这篇博客主要用于记录字符串的一些操作函数，以便于在逆向识别的时候可以顺利的还原为函数。这里因为在release版下其字符串操作函数会内嵌汇编，也就是说并不是使用call来调用函数，所以我们需要来逆向识别一下。

所以下面我们讨论的都是release版下的情况，并且使用的编译...]]></description><category></category></item><item><title><![CDATA[64位汇编入门]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/106718533</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/106718533</guid><author>Wang_1997</author><pubDate>Sat, 20 Jun 2020 17:49:27 +0800</pubDate><description><![CDATA[忽然间想记录一下64位的汇编...这里的话主要就是记录一下和32位汇编的一些比较大的差别，主要就是寄存器和函数调用这两方面，指令什么的话我觉得就遇到查就可以了，有时间的话整理吧。

首先先来看寄存器，如下图



对于上图而言，白色背景部分表示兼容x86的寄存器，支持所有的模式，而对于灰色部分而言，表示扩展的寄存器，只支持64位模式。

先来看通用寄存器，可以发现扩展了8个通用的寄存器，也就是R8-R15，并且由原先的32字节扩展为64个字节，总共16个寄存器


EAX -&gt; RAX
EBX -&g]]></description><category></category></item><item><title><![CDATA[逆向-数组]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/105187370</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/105187370</guid><author>Wang_1997</author><pubDate>Sun, 14 Jun 2020 12:50:17 +0800</pubDate><description><![CDATA[对于数组而言，我们需要理解其数组的寻址公式，而其公式又与其内存的分布息息相关，所以当你了解了其内存分布，那么这个公式自然而然也能推出来。

首先数组有如下两点性质


连续性-排列连续
一致性-类型一致

因为有其连续的特点，所以其内存模型也就比较好理解，下面我们来看一下如下代码


int arr[5] = {0,1,2,3,4}



上面就是其内存模型，对于一致性的特点，可以推定其每个元素占...]]></description><category></category></item><item><title><![CDATA[逆向-函数]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104930382</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104930382</guid><author>Wang_1997</author><pubDate>Sun, 07 Jun 2020 14:13:27 +0800</pubDate><description><![CDATA[函数的工作机制主要是依托栈结构来实现的，首先栈的一种后进先出的结构，为什么使用这种数据结构，因为这和我们函数调用的流程很类似，当程序嵌套调用时，最后一个调用的函数总是最先返回。

对于函数，我们先从宏观上大体的先去了解，后面在看一些内部细节，简单理解函数调用的话，就是在程序动态的运行中，每进入一个函数，总有一块独立的栈函数空间供它使用，这段空间可以存储各类函数需要用到信息，如局部变量，参数等等，当...]]></description><category></category></item><item><title><![CDATA[逆向-循环结构]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104871002</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104871002</guid><author>Wang_1997</author><pubDate>Tue, 26 May 2020 16:20:58 +0800</pubDate><description><![CDATA[对于循环结构而言，主要就三种，do-while循环,while循环，for循环，这三种循环，在debug下其特点还是比较明显的，在release下的话可以说基本上都被优化为do-while循环（效率高），所以说release下的循环，根据其汇编代码我们只能做等价的还原。

下面先来看do-while循环


int main(int argc, char* argv[])
{
    int i ...]]></description><category></category></item><item><title><![CDATA[逆向-分支结构下]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104865039</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104865039</guid><author>Wang_1997</author><pubDate>Mon, 18 May 2020 19:03:56 +0800</pubDate><description><![CDATA[上一篇说完IF结构，这一篇就接着总结分支结构中的switch，对于switch结构，编译器共有四种方案提供选择，我们不必去关心编译器何时会选择何种结构，因为这个完全取决于编译器作者，所以我们只需能识别出这四种方案是switch结构即可。

对于switch结构而言，不管哪种方案，其主要分两部分


引导代码
case块集合

对于不同的方案，其case块集合是不变的，主要在于其引导方式的变化。

...]]></description><category></category></item><item><title><![CDATA[逆向-分支结构上]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104861413</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104861413</guid><author>Wang_1997</author><pubDate>Fri, 08 May 2020 17:12:43 +0800</pubDate><description><![CDATA[前面把一些基本的运算都记录完了，后面开始流程结构，其流程结构主要分为分支结构和循环结构。对于流程结构的逆向识别，主要在于首先需要识别是什么，然后识别语句体（花括号上下界位置），因为确定好了这两步后，其里面的主体内容就是前面的基本运算或者又是流程结构（递归进行逐步分解）。

对于流程结构主要就以debug版为主了，因为debug版更加利于研究其结构如何，而release中除了结构以外，还混有一些的优...]]></description><category></category></item><item><title><![CDATA[逆向-三目运算]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104782210</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104782210</guid><author>Wang_1997</author><pubDate>Tue, 28 Apr 2020 13:58:36 +0800</pubDate><description><![CDATA[首先，先简单回顾一下三目运算符（条件表达式）的格式


表达式一 ? 表达式二 : 表达式三

当表达式一的结果为真时，选择执行表达式二，否则执行表达式三。

看完这个格式，很明显这是一个有分支的结构，那么编译器会老老实实的都按分支语句进行编译么，下面我们还是需要来分情况讨论一下。


1.当表达式二或表达式三不为常量
2.表达式二或表达式三为常量
    2.1 当表达式一为0的等值比较,表达式...]]></description><category></category></item><item><title><![CDATA[C++ 虚函数]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/105283141</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/105283141</guid><author>Wang_1997</author><pubDate>Sun, 19 Apr 2020 20:21:01 +0800</pubDate><description><![CDATA[对于虚函数而言，这篇博客主要侧重于理解虚函数的实现机制，也就是如何实现的多态？

在C++中，使用virtual关键字声明的函数为虚函数。当类中有虚函数时，编译器会将该类中所有虚函数的首地址保存在一张表中，这张表也称为虚函数地址表（虚表），在我们代码层面可以理解为函数指针数组。同时编译器还会在类中添加一个隐藏数据成员，该成员称为虚表指针，该指针也就是用于保存前面所说的虚表首地址。

好了，下面就先...]]></description><category></category></item><item><title><![CDATA[逆向-取模运算]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104775975</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104775975</guid><author>Wang_1997</author><pubDate>Wed, 15 Apr 2020 14:15:29 +0800</pubDate><description><![CDATA[除法终于整理结束了，这篇开始整理取模运算，对于取模运算来说，个别的情况还是需要使用除法的，所以除法运算的基础还是得牢靠。

取模也叫取余，表达为 a % b。下面需要对b的情况进行区分来分析


1. 变量
2. 常量
    2.1 无符号
        2.1.1 2的幂
        2.1.2 非2的幂
    2.2 有符号
        2.1.1 2的幂
           ...]]></description><category></category></item><item><title><![CDATA[逆向-除法优化下]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104706858</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104706858</guid><author>Wang_1997</author><pubDate>Fri, 10 Apr 2020 15:11:07 +0800</pubDate><description><![CDATA[由于除法优化实在太多了，所以这一篇继续讲，前面一篇说了除数为正数情况（常量），那么这篇就来说一说除数为负数的情况。首先里面涉及的很多基础知识请翻上一篇查看，其实如果理解了上一篇的那些基本原理，除法为负的情况也是很好理解的，因为除数为负的情况都是在除数为正的情况之上做了一点点的变化。

首先还是先来分一下情况


除数为常量-除数为负数情况
    1.被除数无符号情况
    2.被除数有符号情况...]]></description><category></category></item><item><title><![CDATA[逆向-除法优化上]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104684881</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104684881</guid><author>Wang_1997</author><pubDate>Thu, 02 Apr 2020 23:54:28 +0800</pubDate><description><![CDATA[上一篇说完加减乘的优化，这篇来说说除法，首先先打个铺垫，除法的优化涉及到各种数学公式，这里我们主要探讨一下结论，具体的证明可以参考《C++反汇编与逆向分析技术揭秘》，这里做一个总结。

首先，如果除数为变量时，是没有任何的优化空间的，所以老老实实的上对应的汇编代码即可，所以就不讨论了。下面主要来讨论下除数为常量的情况，并且这个常量还是正数，负数情况下一篇博客介绍。

首先，先来看一下需要讨...]]></description><category></category></item><item><title><![CDATA[逆向-加减乘运算]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104680195</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104680195</guid><author>Wang_1997</author><pubDate>Sun, 22 Mar 2020 19:32:34 +0800</pubDate><description><![CDATA[后面打算记录一下逆向识别的学习过程，也就是把每个C语言中的基础关键点都反汇编，然后对比观察。虽然说这里的每一步都是很简单，但是就算简单也还是得看，毕竟每个程序都是由这些一个个简单的点组合而成，当进行反汇编还原时，也就是将反汇编一点点拆分成这若干块的小知识点。

好了，首先看最基础的四则运算，也就是加减乘除，当然这篇博客并不包括除，除法的话下面博客再记录吧（因为优化有些复杂了，怕篇幅过长）。

首先...]]></description><category></category></item><item><title><![CDATA[PE结构-重定位表]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104462848</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104462848</guid><author>Wang_1997</author><pubDate>Wed, 04 Mar 2020 19:41:44 +0800</pubDate><description><![CDATA[首先，先来说一下为什么需要重定位表，先来观察一段程序


00401000 &gt;/$  6A 00            push    0                                ; /Style = MB_OK|MB_APPLMODAL
00401002  |.  68 1D204000      push    0040201D                   ...]]></description><category></category></item><item><title><![CDATA[PE结构-导出表]]></title><link>https://blog.youkuaiyun.com/Wang_1997/article/details/104385701</link><guid>https://blog.youkuaiyun.com/Wang_1997/article/details/104385701</guid><author>Wang_1997</author><pubDate>Mon, 02 Mar 2020 23:36:17 +0800</pubDate><description><![CDATA[在上一篇博客中说了导入表，所谓的导入表，其实相当于记录程序所依赖的函数库信息，类似于你要调用外部函数，总得记录下这个函数在哪个库中，名字或者序号是什么。有了这些信息后，我们就可以LoadLibrary和GetProcAddress获取函数地址了

那么，操作系统是如何来获取函数地址呢，也就是GetProcAddress的实现，这里就涉及到了导出表。导出表，会记录这个库函数的地址是多少，所以简单来说...]]></description><category></category></item></channel></rss>