逆向攻防世界CTF系列41-EASYHOOK

逆向攻防世界CTF系列41-EASYHOOK

看题目是一个Hook类型的,第一次接触,虽然学过相关理论,可以看我的文章

Hook入门(逆向)-CSDN博客

题解参考:https://www.cnblogs.com/c10udlnk/p/14214057.html和攻防世界逆向高手题之EASYHOOK-CSDN博客

int __cdecl main(int argc, const char **argv, const char **envp){HANDLE FileA; // eaxDWORD NumberOfBytesWritten; // [esp+4h] [ebp-24h] BYREFchar Buffer[32]; // [esp+8h] [ebp-20h] BYREFsub_401370(aPleaseInputFla);scanf("%31s", Buffer);if ( strlen(Buffer) == 19 ){sub_401220();// 创建文件 (文件名,表示文件以写入模式打开,文件不允许共享访问(即独占模式),不设置安全属性,创建新文件,文件属性设置为普通		文件,模板文件)FileA = CreateFileA(FileName, 0x40000000u, 0, 0, 2u, 0x80u, 0);// (文件句柄:表示目标文件,写入的数据,表示写入的字节数,写入的实际字节数存储位置,同步写入[不使用异步操作])WriteFile(FileA, Buffer, 0x13u, &NumberOfBytesWritten, 0);sub_401240(Buffer, &NumberOfBytesWritten);// 验证函数if ( NumberOfBytesWritten == 1 )sub_401370(aRightFlagIsYou);elsesub_401370(aWrong);system(Command);return 0;}else{sub_401370(aWrong);system(Command);return 0;}
}

跟进401240

int __cdecl sub_401240(const char *a1, _DWORD *a2)
{int result; // eaxunsigned int v3; // kr04_4char v4[24]; // [esp+Ch] [ebp-18h] BYREFresult = 0;strcpy(v4, "This_is_not_the_flag");v3 = strlen(a1) + 1;if ( (int)(v3 - 1) > 0 ){while ( v4[a1 - v4 + result] == v4[result] ){if ( ++result >= (int)(v3 - 1) ){if ( result == 21 ){result = (int)a2;*a2 = 1;}return result;}}}return result;
}

v4[a1 - v4 + result] == v4[result]??,完全不通啊

还看了汇编源码,没看懂 0.0

看下sub_401220先

int sub_401220()
{HMODULE LibraryA; // eaxDWORD CurrentProcessId; // eax// 1. 获取当前进程句柄// GetCurrentProcessId:获取当前进程的进程 ID。// OpenProcess:使用当前进程 ID,以 0x1F0FFFu 权限打开当前进程CurrentProcessId = GetCurrentProcessId();hProcess = OpenProcess(0x1F0FFFu, 0, CurrentProcessId);// 2. 加载目标库和获取函数地址// 动态加载一个DLL文件。// 成功后返回该库的模块句柄 LibraryA。// GetProcAddress:从 LibraryA 中获取目标函数(ProcName)的地址,存储到 WriteFile_0。函数签名定义为 BOOL WriteFile(...)。LibraryA = LoadLibraryA(LibFileName);WriteFile_0 = (BOOL (__stdcall *)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED))GetProcAddress(LibraryA, ProcName);// 3. 检查函数是否获取成功lpAddress = WriteFile_0;if ( !WriteFile_0 )return sub_401370((int)aApi);// 4. 保存原函数的前几字节// 将 WriteFile_0 的前 5 字节保存到 unk_40C9B4 中。_DWORD:前 4 字节。_BYTE:第 5 字节。unk_40C9B4 = *(_DWORD *)lpAddress;*((_BYTE *)&unk_40C9B4 + 4) = *((_BYTE *)lpAddress + 4);// 5. 计算跳转偏移量// byte_40C9BC = -23:一个额外的字节赋值(可能和跳转相关)// 计算一个偏移量,用于跳转到 sub_401080。byte_40C9BC = -23;dword_40C9BD = (char *)sub_401080 - (char *)lpAddress - 5;return sub_4010D0();
}

这里犯了个错,不是-23而是0XE9,是JMP的机器码指令

image-20241118215218470

byte_40C9BC和dword_40C9BD是相邻的,连起来就是 jmp xxxx四个字节

偏移地址=目标地址-当前地址-5(jmp和其后四位地址共占5个字节)。所以前面直接用E9,这里直接用偏移地址就省去编译生成机器码那一步。

看看sub_4010D0()

BOOL sub_4010D0()
{DWORD v1; // [esp+4h] [ebp-8h] BYREFDWORD flOldProtect; // [esp+8h] [ebp-4h] BYREFv1 = 0;// hProcess:目标进程的句柄。// lpAddress:目标内存地址// 5u:操作的字节数。// 4u:新的内存保护属性(可读写)。// &flOldProtect:存储原始内存保护属性。VirtualProtectEx(hProcess, lpAddress, 5u, 4u, &flOldProtect);//  byte_40C9BC 的内容写入目标进程中 lpAddress 开始的 5 字节区域WriteProcessMemory(hProcess, lpAddress, &byte_40C9BC, 5u, 0);return VirtualProtectEx(hProcess, lpAddress, 5u, flOldProtect, &v1);
}

jmp那里会跳转到目标地址sub_401080处,双击跟踪该函数:

int __stdcall sub_401080(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped)
{int v5; // ebxv5 = sub_401000(lpBuffer, nNumberOfBytesToWrite);sub_401140();WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);if ( v5 )*lpNumberOfBytesWritten = 1;// 这里才是真正的校验结果的验证return 0;
}

sub_401000();才是真正的加密函数

BOOL sub_401140()
{DWORD v1; // [esp+4h] [ebp-8h] BYREFDWORD flOldProtect; // [esp+8h] [ebp-4h] BYREFv1 = 0;VirtualProtectEx(hProcess, lpAddress, 5u, 4u, &flOldProtect);WriteProcessMemory(hProcess, lpAddress, &unk_40C9B4, 5u, 0);return VirtualProtectEx(hProcess, lpAddress, 5u, flOldProtect, &v1);
}
int __cdecl sub_401000(int a1, int a2)
{char i; // alchar v3; // blchar v4; // clint v5; // eaxfor ( i = 0; i < a2; ++i ){if ( i == 18 ){*(_BYTE *)(a1 + 18) ^= 0x13u;}else{if ( i % 2 )v3 = *(_BYTE *)(i + a1) - i;elsev3 = *(_BYTE *)(i + a1 + 2);*(_BYTE *)(i + a1) = i ^ v3;}}v4 = 0;if ( a2 <= 0 )return 1;v5 = 0;while ( byte_40A030[v5] == *(_BYTE *)(v5 + a1) ){v5 = ++v4;if ( v4 >= a2 ) return 1;}return 0;
}

解密代码


enc = [0x61, 0x6A, 0x79, 0x67, 0x6B, 0x46, 0x6D, 0x2E, 0x7F, 0x5F,0x7E, 0x2D, 0x53, 0x56, 0x7B, 0x38, 0x6D, 0x4C, 0x6E
]flag=list("-------------------")for i in range(len(enc)):if i == 18:enc[i] ^= 0x13else:v3 = enc[i] ^ iif i % 2 == 1:flag[i] = chr(v3 + i)else:flag[i + 2] = chr(v3)for i in range(len(enc)):print(flag[i],end='')

引用别人博客的一句话:

现在程序流程就很明朗了,粗略来看程序流程是CreateFileA->(lpAddress里存的指令)WriteFile->sub_401240,但是在经过sub_401220()的处理以后,变成了CreateFileA->(lpAddress里存的指令)sub_401080->sub_401240。

sub_401240中即使不符合也不会给NumberOfBytesWritten置成0

nd=‘’)


> 引用别人博客的一句话:> > 现在程序流程就很明朗了,粗略来看程序流程是CreateFileA->(lpAddress里存的指令)WriteFile->sub_401240,但是在经过sub_401220()的处理以后,变成了CreateFileA->(lpAddress里存的指令)sub_401080->sub_401240。sub_401240中即使不符合也不会给NumberOfBytesWritten置成0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/61049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows文件资源管理器增强工具

引言&#xff1a; 资源管理器在我们使用电脑时是经常用到的&#xff0c;各种文件资源等的分类整理都离不开它。但是Windows Explorer确实不好用&#xff0c;不智能&#xff0c;不符合人体工程学。特别是在一些场合&#xff0c;在打开的一堆文件夹里&#xff0c;想从中找到自己要…

【Flask+Gunicorn+Nginx】部署目标检测模型API完整解决方案

【Ubuntu 22.04FlaskGunicornNginx】部署目标检测模型API完整解决方案 文章目录 1. 搭建深度学习环境1.1 下载Anaconda1.2 打包环境1.3 创建虚拟环境1.4 报错 2. 安装flask3. 安装gunicorn4. 安装Nginx4.1 安装前置依赖4.2 安装nginx4.3 常用命令 5. NginxGunicornFlask5.1 ng…

Mac系统下配置 Tomcat 运行环境

下载并解压JDK 下载 根据自己需求下载对应版本的 jdk&#xff0c;我演示使用的是最新版的 jdk23&#xff0c;其他版本过程一样。 如果你是 M 芯片可以点击这个链接下载 如果你是 Intel 芯片可以点击这个链接下载 解压 下载完成后双击解压&#xff0c;将解压出来的文件夹放…

Getx:响应式数据,实现数据的局部刷新

Flutter官网demo实现计数器 这个demo中&#xff0c;如果要更新_count&#xff0c;调用setState就会重新build&#xff0c;这样做比较耗费性能&#xff0c;此时可以使用Getx的响应式状态管理器实现局部刷新 import package:flutter/material.dart;class JiShu extends Stateful…

Dowex 50WX8 ion-exchange resin可以用于去除水中的金属离子(如钠、钾、镁、钙等)和其他杂质,提高水质,11119-67-8

一、基本信息 中文名称&#xff1a;Dowex 50WX8 离子交换树脂 英文名称&#xff1a;Dowex 50WX8 ion-exchange resin CAS号&#xff1a;11119-67-8 供应商&#xff1a;陕西新研博美生物科技 外观&#xff1a;米色至浅棕色或绿棕色粉末/微球状 纯度&#xff1a;≥95% 分子…

使用Tengine 对负载均衡进行状态检查(day028)

本篇文章对于在服务器已经安装了nginx,但却希望使用Tengine 的状态检查或其他功能时使用&#xff0c;不需要卸载服务器上的nginx,思路是使用干净服务器&#xff08;未安装过nginx&#xff09;通过编译安装Tengine&#xff0c;通过对./configure的配置&#xff0c;保证安装Tengi…

2024 - 超火的多模态深度学习公共数据纯生信5+思路分享

超火的多模态深度学习公共数据纯生信5思路分享 多模态深度学习具有处理和整合多种类型信息的优势&#xff0c;特别是在预测患者预后方面能够结合不同类型的生物医学数据&#xff0c;如临床数据、基因表达数据、蛋白质组学数据、成像数据等&#xff0c;进而提高预后预测的准确性…

深入解析大带宽服务器:性能优势与选择指南

一、大带宽服务器是什么&#xff1f; 大带宽服务器指的是具备高网络带宽能力的服务器&#xff0c;通常提供1Gbps、10Gbps甚至更高的网络连接能力。与普通带宽服务器相比&#xff0c;大带宽服务器能够在更短时间内传输大量数据&#xff0c;因此常用于高流量、高并发需求的场景&…

【MySQL】RedHat8安装mysql9.1

一、下载安装包 下载地址&#xff1a;MySQL Enterprise Edition Downloads | Oracle MySQL :: MySQL Community Downloads 安装包&#xff1a;mysql-enterprise-9.1.0_el8_x86_64_bundle.tar 官方 安装文档&#xff1a;MySQL Enterprise Edition Installation Guide 二、安装…

力扣(leetcode)题目总结——动态规划篇

leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏&#xff1a;点击进入 leetcode题目分类 关注走一波 前言&#xff1a;本系列文章初衷是为了按类别整理出力扣&#xff08;leetcode&#xff09;最经典题目&#xff0c…

Vscode/Code-server无网环境安装通义灵码

Date: 2024-11-18 参考材料&#xff1a;https://help.aliyun.com/zh/lingma/user-guide/individual-edition-login-tongyi-lingma?spma2c4g.11186623.0.i0 1. 首先在vscode/code-server插件市场中安装通义插件&#xff0c;这步就不细说了。如果服务器没网&#xff0c;会问你要…

力扣周赛:第424场周赛

&#x1f468;‍&#x1f393;作者简介&#xff1a;爱好技术和算法的研究生 &#x1f30c;上期文章&#xff1a;力扣周赛&#xff1a;第422场周赛 &#x1f4da;订阅专栏&#xff1a;力扣周赛 希望文章对你们有所帮助 第一道题模拟题&#xff0c;第二道题经典拆分数组/线段树都…

STM32单片机设计防儿童人员误锁/滞留车内警报系统

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 近年来在车辆逐渐普及的情况下&#xff0c;由于家长的疏忽&#xff0c;将…

Vue Canvas实现区域拉框选择

canvas.vue组件 <template><div class"all" ref"divideBox"><!-- 显示图片&#xff0c;如果 imgUrl 存在则显示 --><img id"img" v-if"imgUrl" :src"imgUrl" oncontextmenu"return false" …

开源音乐分离器Audio Decomposition:可实现盲源音频分离,无需外部乐器分离库,从头开始制作。将音乐转换为五线谱的程序

今天给大家分析一个音频分解器&#xff0c;通过傅里叶变换和信封匹配分离音乐中的各个音符和乐器&#xff0c;实现音乐到乐谱的转换。将音乐开源分离为组成乐器。该方式是盲源分离&#xff0c;从头开始制作&#xff0c;无需外部乐器分离库。 相关链接 代码&#xff1a;https:…

智慧安防丨以科技之力,筑起防范人贩的铜墙铁壁

近日&#xff0c;贵州省贵阳市中级人民法院对余华英拐卖儿童案做出了一审宣判&#xff0c;判处其死刑&#xff0c;剥夺政治权利终身&#xff0c;并处没收个人全部财产。这一判决不仅彰显了法律的威严&#xff0c;也再次唤起了社会对拐卖儿童犯罪的深切关注。 余华英自1993年至2…

【原创】java+ssm+mysql房屋租赁管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

Linux高阶——1116—环形队列生产者消费者

目录 1、环形队列 2、生产者消费者 环形队列数组实现代码 成功截图 1、环形队列 相比于线性队列&#xff0c;环形队列可以有效避免访问越界问题&#xff0c;使用下标访问队列元素时&#xff0c;到达末尾后下标归0&#xff0c;返回起始位置&#xff0c;使用下标运算即可 a…

构建SSH僵尸网络

import argparse import paramiko# 定义一个名为Client的类&#xff0c;用于表示SSH客户端相关操作 class Client:# 类的初始化方法&#xff0c;接收主机地址、用户名和密码作为参数def __init__(self, host, user, password):self.host hostself.user userself.password pa…

199. 二叉树的右视图【 力扣(LeetCode) 】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 199. 二叉树的右视图 一、题目描述 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 二…