吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 646|回复: 7
收起左侧

[求助] 请教各位这两行代码是否等价?

[复制链接]
你好,再见 发表于 2025-5-6 09:39
我需要读取目标进程PEB当中存储的模块列表。
https://learn.microsoft.com/zh-cn/windows/win32/api/winternl/ns-winternl-peb
https://learn.microsoft.com/zh-cn/windows/win32/api/winternl/ns-winternl-peb_ldr_data
PROCESS_BASIC_INFORMATION -> PPEB -> PPEB_LDR_DATA -> LIST_ENTRY -> LDR_DATA_TABLE_ENTRY结构的第二个成员。

我翻了openark的源代码第921行,它是这样写的:
https://github.com/BlackINT3/none/blob/master/src/unone/process/unone-ps.cpp#L921
[C++] 纯文本查看 复制代码
1
2
node = ldr.InLoadOrderModuleList;
last = (LIST_ENTRY64*)((ULONG64)peb.Ldr + FIELD_OFFSET(PEB_LDR_DATA64, InLoadOrderModuleList));

然后我又问AI它也是这么写,我就不太理解last为什么不能直接赋值为ldr.InLoadOrderModuleList呢?
我认为ldr.InLoadOrderModuleList(LIST_ENTRY64*)((ULONG64)peb.Ldr + FIELD_OFFSET(PEB_LDR_DATA64, InLoadOrderModuleList))是等价的。
求大佬们解惑

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 你好,再见 发表于 2025-5-6 10:07
已经晕了噢,我暂时按openark那样写叭
苏紫方璇 发表于 2025-5-6 10:36
翻了下代码,我有一个是这么写的
[C++] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
9
_PEB *pPeb;
pPeb = (_PEB *)__readfsdword(0x30);
PmPEB_LDR_DATA ldr = (PmPEB_LDR_DATA)pPeb->Ldr;
PLIST_ENTRY head, next;
PLDR_MODULE ldrm;
 
 
head = &(ldr->InLoadOrderModuleList);
next = head->Flink;

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
你好,再见 + 3 + 1 谢谢@Thanks!

查看全部评分

stacia 发表于 2025-5-6 12:20
L1是结构体赋值,执行的动作其实是拷贝,L2是结构体指针的赋值,没有拷贝操作;
以Openark代码为例,L921是获取加载模块的链表的表头,存储到node,L922是通过父结构体PEB_LDR_DATA64的偏移,获取子结构体加载模块的链表的地址(因为是双向链表,即是头也是尾),存储到last里;
再下面whiile循环按照加载顺序依次收集被加载模块的LDR_DATA_TABLE_ENTRY数据并存到info里,同时更新node,最后当整个链表遍历一遍后,退出while循环

免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
你好,再见 + 2 + 1 谢谢@Thanks!

查看全部评分

 楼主| 你好,再见 发表于 2025-5-6 13:12
stacia 发表于 2025-5-6 12:20
L1是结构体赋值,执行的动作其实是拷贝,L2是结构体指针的赋值,没有拷贝操作;
以Openark代码为例,L921 ...

已经有面试的感觉了
 楼主| 你好,再见 发表于 2025-5-9 01:56
本帖最后由 你好,再见 于 2025-5-9 02:13 编辑

我把所有的坑都踩了,目标进程和当前进程没分清楚。。
(LIST_ENTRY64*)((ULONG64)peb.Ldr + FIELD_OFFSET(PEB_LDR_DATA64, InLoadOrderModuleList))计算结果是目标进程中ldr->InLoadOrderModuleList的地址
————————————————
3楼大佬的写法和openark的写法都是正确的,不过后续的循环判断条件不同!!!
 楼主| 你好,再见 发表于 2025-5-9 02:15
stacia 发表于 2025-5-6 12:20
L1是结构体赋值,执行的动作其实是拷贝,L2是结构体指针的赋值,没有拷贝操作;
以Openark代码为例,L921 ...

你说得对L1是结构体赋值,L2是目标进程中的结构体指针赋值,我忽略了这一点,直接对L1取了指针导致后面出错。
stacia 发表于 2025-5-11 10:19
你好,再见 发表于 2025-5-9 02:15
你说得对L1是结构体赋值,L2是目标进程中的结构体指针赋值,我忽略了这一点,直接对L1取了指针导致后面出 ...

嗯是的,不过一直奇怪为什么不用取地址符直接取,而是用父结构体基址+域偏移的方法取得,没做过实验,是不是前者有坑
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-28 18:55

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表