zoukankan      html  css  js  c++  java
  • OD 实验(十七)

    程序:

    运行程序

    弹出一个对话框,点击 OK

    来到主界面,点击 Help -> Register Now

    这是输入注册码的地方

    按关闭程序的按钮

    会提示剩下 30 天的使用时间

    用 Resscope 载入程序

    在 Dialog 下找到程序要退出时的那个对话框

    在 100 处找到该对话框

    103 为 lpTemplateName 对话框模板

    逆向:

    用 OD 载入程序

    右键 -> 查找 -> 所有命令

    64 为 100 的十六进制

    找到很多 push 0x64 的指令

    右键 -> 在每个命令上设置断点

    跑一下程序

    程序停在该断点处,此时程序还没运行起来,而且那个对话框是在程序被关闭的时候弹出的

    按 F9 继续运行

    程序运行起来后,直接关闭程序

    此时停在该断点处,该处就是要弹出对话框的地方,可以把其它断点都去掉了

    这个 call 指令就是显示模态对话框的指令

    往上拉一点

    这里有个 je 跳转指令,如果执行跳转的话,将跳过那个 call 指令

    je 指令上面的 cmp 指令把 eax 和 1 进行比较,如果 eax 等于 1,就能执行跳转

    而 eax 的值是 call 指令调用的函数返回的值

    在 call 指令下一个断点,跑一下程序

    按退出程序的按钮之后,停在了 call 断点处

    按 F7 步入

    按 F8 往下走

    在这里调用了一个 API 函数 RegOpenKeyEx,这个 API 函数用于打开一个注册表的键,注册表键值不区分大小写

    该函数如果调用成功,则返回0(ERROR_SUCCESS)。否则,返回值为文件 WINERROR.h 中定义的一个非零的错误代码

    按 F8 接着往下走

    这条指令把 API 函数 RegQueryValueEx 的地址传给 esi

    按 F8 接着往下走

    这里有个 call esi,就是调用 RegQueryValueEx 函数

    RegQueryValueEx 用于检索一个已打开的注册表句柄中,指定的注册表键的类型和设置值

    函数调用成功的话返回 0,如果失败返回错误代码

    函数原型:

    LONG WINAPI RegQueryValueEx(
        HKEY hKey,            // 一个已打开项的句柄,或者指定一个标准项名
        LPCTSTR lpValueName,  // 要查询注册表键值的名字字符串,注册表键的名字,以空字符结束
        LPDWORD lpReserved,   // 未用,设为零
        LPDWORD lpType,       // 用于装载取回数据类型的一个变量
        LPBYTE lpData,        // 用于装载指定值的一个缓冲区
        LPDWORD lpcbData      // 用于装载lpData缓冲区长度的一个变量,一旦返回,它会设为实际装载到缓冲区的字节数
    );
    

    RegQueryValueEx 会把找到的键的值存放到数据缓冲区

    它的参数按反依次对应

    该函数要拿到 RegName3 键的值,把结果存到 edx 的地址中

    edx 对应 lpData,ecx 对应 lpcbData

    edx、ecx 分别为这两个地址

    调用完该函数后,该函数返回 2,也就是调用失败,因为在注册表中找不到 RegName3

    按 F8 接着往下走

    走到一个跳转已实现的跳转指令

    如果该跳转指令实现跳转的话就会跳到函数的末尾

    如果该跳转指令不实现跳转,接着往下走

    就会再一次调用 RegQueryValueEx 函数,这次是要查找 RegCode3 键的值

    会存放到 edx 的地址中

    按 F8 接着往下走

    这个跳转指令也是跳转到函数的末尾

    让其不跳转

    这两句把这两个地址传给 edx 和 ecx,而这两个地址刚才都传给 edx 过,用来存放 RegName3 和 RegCode3 的结果

    分别将 ecx 和 edx 入栈,然后通过 call 调用一个函数来验证他们

    按 F7 步入

    该函数有两个返回值

    一个为 1,一个为 0

    按 F8 往下走

    有个已实现的跳转

    如果跳转将跳过返回值为 1 的 retn

    不让其跳转,接着往下走

    接下来的三条跳转指令都是跟第一条语句一样的跳法,看来返回值为 1 才是我们想要的

    让这三条语句不跳,继续往下走

    这是最后一个跳转指令,让它不跳

    接着往下走

    函数返回了 1

    接着往下走,一路默认

    走到 retn 指令,此时 eax 的值还是为 1

    eax 的值为 1,cmp 指令把 eax 的值 和 1 比较,如果相等,je 就执行跳转

    跳转就跳过了调用对话框的那个 call 指令

  • 相关阅读:
    MongoDB Shell
    mongo 日记
    java 堆栈 静态
    面向对象(2)
    面向对象(1)
    mongo 学习笔记
    深入浅出学Spring Data JPA
    java记录
    mongodb 2.6 window 安装启动服务
    CF1012F Passports
  • 原文地址:https://www.cnblogs.com/sch01ar/p/9747591.html
Copyright © 2011-2022 走看看