当前位置: 首页 > news >正文

一种动态地址的查询

背景

当我们注入一个进程,通过函数地址进行call时经常会遇到这样的一个问题。对方程序每周四会自动更新。更新后之前的函数地址就变化了,然后需要重新找地址。所以,我就使用了一个动态查询的方式。

第一步:先为需要call的函数生成特征码。特征码其实就是反汇编后,去掉地址,只留操作符。


function make_search(v: dword; ms: TMemoryStream; maxsize: integer): string;
var
  offset: dword;
  isnot_ret: boolean;
  description: string;
begin
  ms.Clear;
  Result := '';
  offset := v;
  isnot_ret := true;
  while isnot_ret do
    begin
      isnot_ret := pbyte(offset)^ <> $C3;
      disassemble_find(offset, description, ms);
      if Result <> '' then
        Result := Result + #13#10;
      Result := Result + description;
      if ms.Size > 1024 then
        Break;
    end;
end;

disassemble_find 函数的行数太多了。

function disassemble_find(var offset: dword; var description: string; ms_find: TMemoryStream): string; overload;
var
  memory: TMemory;
  actualread: dword;
  startoffset: dword;
  tempresult: string;
  tempst: string;
  wordptr: ^word;
  dwordptr: ^dword;
  dwordptr2: ^dword;
  singleptr: ^single;
  doubleptr: ^double;
  extenedptr: ^extended;
  int64ptr: ^int64;
  i, j: integer;

  prefix: TPrefix;
  prefix2: TPrefix;
  isprefix: boolean;

  last: dword;
  foundit: boolean;
  search_size: integer;
  str_tmp: string;
begin
  search_size := 0;
  result := inttohex(offset, 8) + ' - ';

  isprefix := true;
  prefix := [$F0, $F2, $F3, $2E, $36, $3E, $26, $64, $65, $66, $67];
  prefix2 := [];

  //forced 16-bit
  if mode16 then
    prefix2 := prefix2 + [$66];

  startoffset := offset;

  readmemory(pointer(offset), addr(memory), 24, actualread);

  /

  if actualread > 0 then
    begin
      //I HATE THESE...   (I propably will not add them all, but I'll see how far I get)

      while isprefix do
        begin
          inc(offset);
          if memory[0] in prefix then
            begin
              result := result + inttohexs(memory[0], 2) + ' ';
              isprefix := true;
              inc(startoffset);
              prefix2 := prefix2 + [memory[0]];
              ReadMemory(pointer(offset), addr(memory), 24, actualread);
            end
          else
            isprefix := false;
        end;

      if $F0 in prefix2 then tempresult := 'lock ';
      if $F2 in prefix2 then tempresult := tempresult + 'repne ';
      if $F3 in prefix2 then tempresult := tempresult + 'repe ';

      case memory[0] of //opcode
        $00:
          begin
            description := 'Add';
            tempresult := tempresult + 'add ' + MODRM(memory, prefix2, 1, 2, last) + r8(memory[1]);
            inc(offset, last - 1);
          end;

        $01:
          begin
            description := 'Add';
            if $66 in prefix2 then
              tempresult := tempresult + 'ADD ' + MODRM(memory, prefix2, 1, 1, last) + r16(memory[1])
            else
              tempresult := tempresult + 'ADD ' + MODRM(memory, prefix2, 1, 0, last) + r32(memory[1]);
            inc(offset, last - 1);

          end;

        $02:
          begin
            description := 'Add';
            tempresult := tempresult + 'ADD ' + r8(memory[1]) + ',' + MODRM(memory, prefix2, 1, 2, last);
            tempresult := copy(tempresult, 0, length(tempresult) - 1);
            inc(offset, last - 1);
          end;

        $03:
          begin
            description := 'Add';
            if $66 in prefix2 then
              tempresult := tempresult + 'ADD ' + r16(memory[1]) + ',' + MODRM(memory, prefix2, 1, 1, last)
            else
              tempresult := tempresult + 'ADD ' + r32(memory[1]) + ',' + MODRM(memory, prefix2, 1, 0, last);
            tempresult := copy(tempresult, 0, length(tempresult) - 1);
            inc(offset, last - 1);
          end;

        $04:
          begin
            description := 'Add x to y';
            tempresult := tempresult + 'ADD AL,' + inttohexs(memory[1], 2);
            inc(offset);
          end;

        $05:
          begin
            description := 'Add x to y';
            wordptr := @memory[1];
            dwordptr := @memory[1];
            if $66 in prefix2 then
              begin
                tempresult := tempresult + 'ADD AX,' + inttohexs(wordptr^, 4);
                inc(offset, 2);
              end
            else
              begin
                tempresult := tempresult + 'ADD EAX,' + inttohexs(dwordptr^, 8);
                inc(offset, 4);
              end;
          end;

第二步:查询函数地址

function search_address(ms_search: TMemoryStream; sl: tstringlist): string;
var
  idx, i: integer;
  ms: TMemoryStream;
  Mem: TMemoryBasicInformation;
  dwProtect, temp: cardinal;
  msize: dword;
  canread, willVirtualProtect: boolean;

  procedure dosearch;
  var
    count, idx, i, l: integer;
    s: string;
    ms_old: TMemoryStream;
    ms: TMemoryStream;
  begin
    ms_search.Position := 0;
    ms_search.Read(count, sizeof(ms_search));
    for i := 1 to count do
      begin
        ms := TMemoryStream.Create;
        ms_old := TMemoryStream.Create;

        ms_search.Read(l, sizeof(l));
        setlength(s, l);
        ms_search.Read(s[1], l);
        ms_search.Read(l, sizeof(l));
        ms_old.CopyFrom(ms_search, l);

        ms_search.Read(l, sizeof(l));
        ms.CopyFrom(ms_search, l);

        //if SameText('Py_GetVersion', s) then
        begin
          idx := search_ms(integer(Mem.BaseAddress), Mem.RegionSize, ms_old);
          if idx < 0 then
            begin
              idx := search_ms(integer(Mem.BaseAddress), Mem.RegionSize, ms);
            end;
          if idx >= 0 then
            begin
              sl.AddObject(s, pointer(idx));
              if Result <> '' then
                Result := Result + #13#10;
              Result := Result + s + '=' + IntToStr(idx - integer(Mem.BaseAddress));
            end;
        end;
        FreeAndNil(ms);
        FreeAndNil(ms_old);
      end;
  end;
begin
  Result := '';
  idx := -1;
  if length(Mems) <= 0 then
    u_mem.test;
  for i := 0 to high(Mems) do
    begin
      if SameText('mhmain.dll', GetItemFilePath(Mems[i], Modules)) then
        if Mems[i].RegionSize > 1024 * 1024 * 4 then
          begin
            Mem := Mems[i];
            idx := i;
            Break;
          end;
    end;
  if idx < 0 then
    exit;
  canread := not IsBadReadPtr(mem.BaseAddress, mem.RegionSize);
  if not canread then
    begin
      if VirtualProtect(mem.BaseAddress, mem.RegionSize, PAGE_EXECUTE_READWRITE, @dwProtect) then
        begin
          canread := true;
          willVirtualProtect := true;
        end;
    end;
  if canread then
    begin
      dosearch;
    end;
  if willVirtualProtect then
    VirtualProtect(mem.BaseAddress, mem.RegionSize, dwProtect, @temp);
end;
 

注意

同一个函数可能查到多个地址,但是可以根据多个地址进行校验。命中的范围最集中的那个范围中的地址,一般都是正确的地址。

相关文章:

一种动态地址的查询

背景 当我们注入一个进程&#xff0c;通过函数地址进行call时经常会遇到这样的一个问题。对方程序每周四会自动更新。更新后之前的函数地址就变化了&#xff0c;然后需要重新找地址。所以&#xff0c;我就使用了一个动态查询的方式。 第一步&#xff1a;先为需要call的函数生…...

周雨彤:用角色与生活,诠释审美的艺术

提到内娱审美优秀且持续在线的女演员&#xff0c;周雨彤绝对是其中最有代表性的一个。 独树一帜的表演美学 作为新生代演员中的实力派代表&#xff0c;周雨彤凭借细腻的表演和对角色的深度共情&#xff0c;在荧幕上留下了多个令人难忘的“出圈”形象。在《我在他乡挺好的》中…...

使用jks给空apk包签名

1、在平台官方下载空的apk包&#xff08;上传应用时有提醒下载&#xff09; 2、找到jdk目录&#xff0c;比如C:\Program Files\Java\jdk1.8\bin&#xff0c;并把下载的空包apk和jks文件放到bin下 3、以管理员身份运行cmd&#xff0c;如果不是管理员会签名失败 4、用cd定位到…...

500. 键盘行 771. 宝石与石头 简单 find接口的使用

500. 键盘行1 给你一个字符串数组 words &#xff0c;只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。 请注意&#xff0c;字符串 不区分大小写&#xff0c;相同字母的大小写形式都被视为在同一行。 美式键盘 中&#xff1a; 第一行由字符 "qwer…...

仙剑世界手游新手攻略 仙剑世界能用云手机玩吗

欢迎来到《仙剑世界》手游的仙侠世界&#xff01;作为新手玩家&#xff0c;以下是一些详细的攻略和建议&#xff0c;帮助你快速上手并享受游戏的乐趣。 一、新手职业推荐 1.轩辕&#xff1a;这是一个偏辅助的职业&#xff0c;可以给队友提供输出加成等增益效果&#xff0c;不过…...

[题解]2024CCPC重庆站-小 C 的神秘图形

Sources&#xff1a;K - 小 C 的神秘图形Abstract&#xff1a;给定正整数 n ( 1 ≤ n ≤ 1 0 5 ) n(1\le n\le 10^5) n(1≤n≤105)&#xff0c;三进制字符串 n 1 , n 2 ( ∣ n 1 ∣ ∣ n 2 ∣ n ) n_1,n_2(|n_1||n_2|n) n1​,n2​(∣n1​∣∣n2​∣n)&#xff0c;按如下方法…...

NPS内网穿透SSH使用手册

1、说明 nps-一款轻量级、高性能、功能强大的内网穿透代理服务器 github地址&#xff1a;https://github.com/ehang-io/nps 官网文档地址&#xff1a;https://ehang-io.github.io/nps/#/?idnps 2、服务端 下载地址&#xff1a;https://github.com/ehang-io/nps/releases 下…...

大幂计算和大阶乘计算【C语言】

大幂计算&#xff1a; #include<stdio.h> long long int c[1000000]{0}; int main() {long long a,b,x1;c[0]1;printf("请输入底数&#xff1a;");scanf("%lld",&a);printf("请输入指数&#xff1a;");scanf("%lld",&b…...

【Linux】详谈 进程控制

目录 一、进程是什么 二、task_struct 三、查看进程 四、创建进程 4.1 fork函数的认识 4.2 2. fork函数的返回值 五、进程终止 5.1. 进程退出的场景 5.2. 进程常见的退出方法 5.2.1 从main返回 5.2.1.1 错误码 5.2.2 exit函数 5.2.3 _exit函数 5.2.4 缓冲区问题补…...

Linux top 命令

作用 top 是一个实时系统监控工具&#xff0c;用于查看系统的资源使用情况和进程状态。 示例 以下是一些常用的 top 命令示例&#xff1a; top &#xff1a;动态显示结果&#xff0c;每 3 秒刷新一次。 top -d 2&#xff1a;动态显示结果&#xff0c;每 2 秒刷新一次。 top …...

Leetcode 424-替换后的最长重复字符

给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符&#xff0c;并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。 在执行上述操作后&#xff0c;返回 包含相同字母的最长子字符串的长度。 题解 可以先做LCR 167/Leetcode 03再做本题 滑动窗口&…...

《StyleDiffusion:通过扩散模型实现可控的解耦风格迁移》学习笔记

paper&#xff1a;2308.07863 目录 摘要 1、介绍 2、相关工作 2.1 神经风格迁移&#xff08;NST&#xff09; 2.2 解耦表示学习&#xff08;DRL&#xff09; 2.3 扩散模型&#xff08;Diffusion Models&#xff09; 3、方法 3.1 风格移除模块 3.2 风格转移模块 3.3 …...

Django 创建表时 “__str__ ”方法的使用

在 Django 模型中&#xff0c;__str__ 方法是一个 Python 特殊方法&#xff08;也称为“魔术方法”&#xff09;&#xff0c;用于定义对象的字符串表示形式。它的作用是控制当对象被转换为字符串时&#xff0c;应该返回什么样的内容。 示例&#xff1a; 我在初学ModelForm时尝…...

图像处理之CSC

CSC 是 Color Space Conversion&#xff08;色彩空间转换&#xff09;的缩写&#xff0c;它涉及图像处理中的亮度、饱和度、对比度和色度等参数的调整。这些参数是图像处理中的核心概念&#xff0c;通常用于描述和操作图像的颜色信息。 以下是亮度、饱和度、对比度和色度与 CS…...

C语言数组之二维数组

C语言 主要内容 数组 二维数组 数组 二维数组 定义 二维数组本质上是一个行列式的组合&#xff0c;也就是说二维数组由行和列两部分组成&#xff0c;属于多维数组。二维数组数据是通过行列进行解读。二维数组可被视为一个特殊的一维数组&#xff0c;相当于二维数组又是一…...

PyTorch 源码学习:阅读经验 代码结构

分享自己在学习 PyTorch 源码时阅读过的资料。本文重点关注阅读 PyTorch 源码的经验和 PyTorch 的代码结构。因为 PyTorch 不同版本的源码实现有所不同&#xff0c;所以笔者在整理资料时尽可能按版本号升序&#xff0c;版本号见标题前[]。最新版本的源码实现还请查看 PyTorch 仓…...

vite+vue3开发低版本浏览器不支持es6语法的问题排坑笔记

重要提示&#xff1a;请首先完整阅读完文章内容后再操作&#xff0c;以免不必要的时间浪费&#xff01;切记&#xff01;&#xff01;&#xff01;在使用vitevue3开发unapp项目时&#xff0c;发现低版本浏览器不兼容es6的语法&#xff0c;如“?.” “??” 等&#xff0c;为了…...

C语言中printf()函数,格式输出符

在 C 语言中&#xff0c;printf() 函数的格式输出符&#xff08;格式说明符&#xff09;用于控制输出的格式和数据类型。以下是常见的格式说明符及其用法&#xff1a; 基本格式符 打印各种类型的值 格式输出符数据类型说明%dint输出有符号十进制整数%uunsigned int输出无符号…...

AI 编程工具—Cursor 进阶篇 数据分析

AI 编程工具—Cursor 进阶篇 数据分析 上一节课我们使用Cursor 生成了北京房产的销售数据,这一节我们使用Cursor对这些数据进行分析,也是我们尝试使用Cursor 去帮我们做数据分析,从而进一步发挥Cursor的能力,来帮助我们完成更多的事情 案例一 房产销售数据分析 @北京202…...

青少年编程与数学 02-009 Django 5 Web 编程 20课题、测试

青少年编程与数学 02-009 Django 5 Web 编程 20课题、测试 一、软件测试二、自动化测试三、单元测试四、Django 单元测试&#xff08;一&#xff09;、创建测试用例&#xff08;二&#xff09;、运行测试&#xff08;三&#xff09;、常用测试功能 课题摘要: 本文全面介绍了软件…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...