|
分享源码
界面截图: |
- |
是否带模块: |
- |
备注说明: |
- |
机器 汇编->C->高级语言->提示词->母语->图形化可视化 人
人机交互的鸿沟已经逐渐被抹平,语言障碍再也不会成为编程的障碍了。
希望易友有什么好东西分享给大家,毕竟易语言这个小圈子是易友的后院,是其他人进不来的。我们来看一个热门源码:
R3保护自己的代码段不被修改,直接废掉WriteMemory
https://bbs.125.la/thread-14748601-1-2.html
代码如下:
|
AddNoChange_File | | | |
BaseAddress | 整数型 | | | |
变量名 | 类 型 | 静态 | 数组 | 备 注 | l_Offset | 整数型 | | | l_Section | MEMORY_BASIC_INFORMATION | | 0 | l_ImageSize | 长整数型 | | | l_SectionHandle | 整数型 | | | l_pViewBase | 整数型 | | | l_ViewSize | 整数型 | | | l_SectionOffset | 长整数型 | | | l_Status | 整数型 | | | MEMORY_BASIC_INFORMATION | MEMORY_BASIC_INFORMATION | | | i | 整数型 | | |
l_Offset = 0 循环判断首 () NtQueryVirtualMemory (-1, BaseAddress + l_Offset, 0, MEMORY_BASIC_INFORMATION, 28, 0 )如果真 (MEMORY_BASIC_INFORMATION.lType ≠ #TYPE_MEM_IMAGE ) 跳出循环 ()加入成员 (l_Section, MEMORY_BASIC_INFORMATION)l_Offset = l_Offset + MEMORY_BASIC_INFORMATION.RegionSize 循环判断尾 (MEMORY_BASIC_INFORMATION.lType = #TYPE_MEM_IMAGE )l_ImageSize = l_Offset l_SectionHandle = 0 l_Status = NtCreateSection (l_SectionHandle, 位或 ( #SECTION_QUERY, #SECTION_MAP_WRITE, #SECTION_MAP_READ, #SECTION_MAP_EXECUTE, #SECTION_EXTEND_SIZE, #SECTION_MAP_EXECUTE_EXPLICIT ), 0, l_ImageSize, #PAGE_EXECUTE_READWRITE, #SEC_COMMIT, 0 ) 如果真 (l_Status ≠ 0 )输出调试文本 (“NtCreateSection创建节对象失败!”)返回 ()l_Status = NtMapViewOfSection (l_SectionHandle, -1, l_pViewBase, 0, 0, 0, l_ViewSize, 1, 0, #PAGE_EXECUTE_READWRITE ) 如果真 (l_Status ≠ 0 )NtClose (l_SectionHandle )输出调试文本 (“NtMapViewOfSection映射节对象失败!”)返回 ()RtlMoveMemory (l_pViewBase, BaseAddress, l_Offset)
l_Status = NtUnmapViewOfSection (-1, l_pViewBase ) 如果真 (l_Status ≠ 0 )NtClose (l_SectionHandle )输出调试文本 (“NtUnmapViewOfSection解除当前失败!”)返回 ()l_Status = NtUnmapViewOfSection (-1, BaseAddress) 如果真 (l_Status ≠ 0 )NtClose (l_SectionHandle )输出调试文本 (“NtUnmapViewOfSection解除原映射失败!”)返回 ()l_pViewBase = l_Section [1].BaseAddress 计次循环首 (取数组成员数 (l_Section ), i )如果真 (l_Section [i ].Protect = #PAGE_READWRITE 或 l_Section [i ].Protect = #PAGE_WRITECOPY 或 l_Section [i ].Protect = #PAGE_EXECUTE_READWRITE 或 l_Section [i ].Protect = #PAGE_EXECUTE_WRITECOPY )l_ViewSize = l_Section [i ].BaseAddress - l_Section [1 ].BaseAddress 跳出循环 ()计次循环尾 ()l_ViewSize = 65536 × 到整数 (l_ViewSize ÷ 65536 ) 如果真 (l_ViewSize ≠ 0 )l_Status = NtMapViewOfSection (l_SectionHandle, -1, l_pViewBase, 0, 0, 0, l_ViewSize, 1, #SEC_NO_CHANGE, #PAGE_EXECUTE )l_Status = NtMapViewOfSection (l_SectionHandle, -1, l_pViewBase + l_ViewSize, 0, 0, l_ViewSize, l_ImageSize - l_ViewSize, 1, #SEC_NO_CHANGE, #PAGE_EXECUTE_READWRITE )NtClose (l_SectionHandle )
现在使用大模型转换成C语言,并且要求变量名和函数名使用中文,以及添加注释:
// 添加NoChange标识的子程序 void 添加NoChange标识 (PVOID 基址) { ULONG 偏移 = 0; MEMORY_BASIC_INFORMATION 内存基本信息; LARGE_INTEGER 映像大小; HANDLE 节句柄 = NULL; PVOID 新基址 = NULL; SIZE_T 新映射大小; LARGE_INTEGER 节偏移; NTSTATUS 状态; int i; // 将节内存信息全部枚举出来 while (TRUE) { 状态 = NtQueryVirtualMemory (NtCurrentProcess (), 基址 + 偏移, MemoryBasicInformation, &内存基本信息, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (内存基本信息.Type != MEM_IMAGE) { // 只要IMAGE部分 break; } 偏移 += 内存基本信息.RegionSize; } 映像大小.QuadPart = 偏移; // 根据原SECTION大小创建一块相同大小的SECTION 状态 = NtCreateSection (&节句柄, SECTION_ALL_ACCESS, NULL, &映像大小, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL); if (状态 != 0) { DbgPrint ("NtCreateSection创建节对象失败!"); return; } // 将其映射到内存 状态 = NtMapViewOfSection (节句柄, NtCurrentProcess (), &新基址, 0, 0, NULL, &新映射大小, ViewShare, 0, PAGE_EXECUTE_READWRITE); if (状态 != 0) { NtClose (节句柄); DbgPrint ("NtMapViewOfSection映射节对象失败!"); return; } // 将需要原数据拷贝到新区段 RtlCopyMemory (新基址, 基址, 偏移); // 解除新区段的映射 状态 = NtUnmapViewOfSection (NtCurrentProcess (), 新基址); if (状态 != 0) { NtClose (节句柄); DbgPrint ("NtUnmapViewOfSection解除当前失败!"); return; } // 解除原IMAGE的映射 状态 = NtUnmapViewOfSection (NtCurrentProcess (), 基址); if (状态 != 0) { NtClose (节句柄); DbgPrint ("NtUnmapViewOfSection解除原映射失败!"); return; } // 计算新的新基址 新基址 = 内存基本信息.BaseAddress; // 计算新映射大小并进行64KB对齐 for (i = 0; i < 内存基本信息.RegionCount; i++) { if (内存基本信息.RegionEntry[i].Protect == PAGE_READWRITE || 内存基本信息.RegionEntry[i].Protect == PAGE_WRITECOPY || 内存基本信息.RegionEntry[i].Protect == PAGE_EXECUTE_READWRITE || 内存基本信息.RegionEntry[i].Protect == PAGE_EXECUTE_WRITECOPY) { 新映射大小 = 内存基本信息.RegionEntry[i].BaseAddress - 内存基本信息.BaseAddress; break; } } 新映射大小 = (新映射大小 + 0xFFFF) & ~0xFFFF; // 64KB对齐 // 分两步映射新区域 if (新映射大小 != 0) { 状态 = NtMapViewOfSection (节句柄, NtCurrentProcess (), 新基址, 0, 0, NULL, 新映射大小, ViewShare, SEC_NO_CHANGE, PAGE_EXECUTE); } 状态 = NtMapViewOfSection (节句柄, NtCurrentProcess (), 新基址 + 新映射大小, 0, 0, (PSIZE_T)新映射大小, 映像大小.QuadPart - 新映射大小, ViewShare, SEC_NO_CHANGE, PAGE_EXECUTE_READWRITE); NtClose (节句柄); }
再试一下转换成C++
// .版本 2 // .子程序 AddNoChange_File, , 公开, 添加NoChange标识 void 添加NoChange标识 (PVOID 基址) { // .参数 BaseAddress, 整数型, , 限于IMAGE映射处理
// .局部变量 l_Offset, 整数型 ULONG 偏移 = 0; // .局部变量 l_Section, MEMORY_BASIC_INFORMATION, , "0", 需要处理的节 MEMORY_BASIC_INFORMATION 内存基本信息[1024]; // 假设最多有1024个内存区域 // .局部变量 l_ImageSize, 长整数型, , , 映像大小 SIZE_T 映像大小; // .局部变量 l_SectionHandle, 整数型, , , 节句柄 HANDLE 节句柄 = NULL; // .局部变量 l_pViewBase, 整数型, , , 映射到的新基址 PVOID 新基址 = NULL; // .局部变量 l_ViewSize, 整数型, , , 映射大小 SIZE_T 映射大小; // .局部变量 l_SectionOffset, 长整数型, , , 节偏移 ULONG_PTR 节偏移; // .局部变量 l_Status, 整数型 NTSTATUS 状态; // .局部变量 MEMORY_BASIC_INFORMATION, MEMORY_BASIC_INFORMATION // .局部变量 i, 整数型 ULONG i; // l_Offset = 0 // .循环判断首 () for (偏移 = 0; ; 偏移 += 内存基本信息[0].RegionSize) { // NtQueryVirtualMemory (-1, BaseAddress + l_Offset, 0, MEMORY_BASIC_INFORMATION, 28, 0) 状态 = NtQueryVirtualMemory (GetCurrentProcess (), 基址 + 偏移, MemoryBasicInformation, 内存基本信息, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS (状态)) { // 输出调试文本 ("NtQueryVirtualMemory查询内存信息失败!") break; }
// .如果真 (MEMORY_BASIC_INFORMATION.lType ≠ #TYPE_MEM_IMAGE ) if (内存基本信息[0].Type != MEM_IMAGE) { // 跳出循环 () break; } // .如果真结束 } // .循环判断尾 (MEMORY_BASIC_INFORMATION.lType = #TYPE_MEM_IMAGE ) 映像大小 = 偏移; // l_SectionHandle = 0 // l_Status = NtCreateSection (l_SectionHandle, 位或 ( #SECTION_QUERY, #SECTION_MAP_WRITE, #SECTION_MAP_READ, #SECTION_MAP_EXECUTE, #SECTION_EXTEND_SIZE, #SECTION_MAP_EXECUTE_EXPLICIT ), 0, l_ImageSize, #PAGE_EXECUTE_READWRITE, #SEC_COMMIT, 0) 状态 = NtCreateSection (&节句柄, SECTION_ALL_ACCESS, NULL, NULL, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS (状态)) { // 输出调试文本 ("NtCreateSection创建节对象失败!") return; }
// .如果真 (l_Status ≠ 0) // 输出调试文本 ("NtCreateSection创建节对象失败!") // 返回 () // .如果真结束
// l_Status = NtMapViewOfSection (l_SectionHandle, -1, l_pViewBase, 0, 0, 0, l_ViewSize, 1, 0, #PAGE_EXECUTE_READWRITE ) 状态 = NtMapViewOfSection (节句柄, GetCurrentProcess (), &新基址, 0, 0, NULL, 0, ViewShare, 0, PAGE_READWRITE); if (!NT_SUCCESS (状态)) { // NtClose (l_SectionHandle) NtClose (节句柄); // 输出调试文本 ("NtMapViewOfSection映射节对象失败!") return; } // .如果真结束
// RtlMoveMemory (l_pViewBase, BaseAddress, l_Offset) RtlMoveMemory (新基址, 基址, 映像大小);
// l_Status = NtUnmapViewOfSection (-1, l_pViewBase) 状态 = NtUnmapViewOfSection (GetCurrentProcess (), 新基址); if (!NT_SUCCESS (状态)) { // NtClose (l_SectionHandle) NtClose (节句柄); // 输出调试文本 ("NtUnmapViewOfSection解除当前失败!") return; } // .如果真结束
// l_Status = NtUnmapViewOfSection (-1, BaseAddress) 状态 = NtUnmapViewOfSection (GetCurrentProcess (), 基址); if (!NT_SUCCESS (状态)) { // NtClose (l_SectionHandle) NtClose (节句柄); // 输出调试文本 ("NtUnmapViewOfSection解除原映射失败!") return; } // .如果真结束
// l_pViewBase = l_Section [1].BaseAddress 新基址 = 内存基本信息[0].BaseAddress;
// .计次循环首 (取数组成员数 (l_Section), i) for (i = 0; i < (sizeof (内存基本信息) / sizeof (MEMORY_BASIC_INFORMATION)); i++) { // .如果真 (l_Section [i].Protect = #PAGE_READWRITE 或 l_Section [i].Protect = #PAGE_WRITECOPY 或 l_Section [i].Protect = #PAGE_EXECUTE_READWRITE 或 l_Section [i].Protect = #PAGE_EXECUTE_WRITECOPY ) if (内存基本信息[i].Protect == PAGE_READWRITE || 内存基本信息[i].Protect == PAGE_WRITECOPY || 内存基本信息[i].Protect == PAGE_EXECUTE_READWRITE || 内存基本信息[i].Protect == PAGE_EXECUTE_WRITECOPY) { // l_ViewSize = l_Section [i].BaseAddress - l_Section [1].BaseAddress 映射大小 = 内存基本信息[i].BaseAddress - 内存基本信息[0].BaseAddress; // 跳出循环 () break; } // .如果真结束 } // .计次循环尾 ()
// l_ViewSize = 65536 × 到整数 (l_ViewSize ÷ 65536) 映射大小 = (映射大小 + 0xFFFF) & ~0xFFFF; // 64KB对齐
// .如果真 (l_ViewSize ≠ 0) if (映射大小 != 0) { // l_Status = NtMapViewOfSection (l_SectionHandle, -1, l_pViewBase, 0, 0, 0, l_ViewSize, 1, #SEC_NO_CHANGE, #PAGE_EXECUTE ) 状态 = NtMapViewOfSection (节句柄, GetCurrentProcess (), 新基址, 0, 0, NULL, 映射大小, ViewShare, SEC_NO_CHANGE, PAGE_EXECUTE); if (!NT_SUCCESS (状态)) { NtClose (节句柄); return; } } // .如果真结束
// l_Status = NtMapViewOfSection (l_SectionHandle, -1, l_pViewBase + l_ViewSize, 0, 0, l_ViewSize, l_ImageSize - l_ViewSize, 1, #SEC_NO_CHANGE, #PAGE_EXECUTE_READWRITE ) 状态 = NtMapViewOfSection (节句柄, GetCurrentProcess (), (PVOID) ( (ULONG_PTR)新基址 + 映射大小), 0, 0, (PSIZE_T)映射大小, 映像大小 - 映射大小, ViewShare, SEC_NO_CHANGE, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS (状态)) { NtUnmapViewOfSection (GetCurrentProcess (), 新基址); NtClose (节句柄); return; }
// NtClose (l_SectionHandle) NtClose (节句柄); }
还给出了解释
这段代码的作用是为一个已经加载到内存中的可执行映像文件添加 SEC_NO_CHANGE 标识。它通过以下步骤实现:
枚举映像在内存中占用的所有内存区域。
根据映像的总大小创建一个新的内存区域(Section)。
将原映像数据复制到新创建的内存区域中。
解除原映像的内存映射。
重新映射新创建的内存区域,并为其添加 SEC_NO_CHANGE 标识。
代码中有一些重要的逻辑流程:
使用循环来枚举映像占用的所有内存区域。
根据内存区域的属性来判断是否为映像的一部分。
计算新映射区域的大小并进行64KB对齐。
分两步映射新区域,第一步映射只读部分,第二步映射可读写部分。
这段代码涉及到的API比较多,所以汉化程度还不够高,换一个RC4的加密算法来体会一下:
/* RC4加密算法 */ #include #include typedef unsigned char 文本型; typedef int 整数型; /* 密钥调度算法 */ void 密钥初始化 (文本型 *密钥,文本型 *状态向量,整数型 密钥长度) { 整数型 计数器; /* 循环计数器 */ 文本型 临时交换值; /* 用于交换状态向量值的临时变量 */
/* 初始化状态向量 */ for (计数器 = 0; 计数器 < 256; 计数器++) 状态向量[计数器] = 计数器;
/* 使用密钥初始化状态向量 */ for (计数器 = 0; 计数器 < 256; 计数器++) { 临时交换值 = 状态向量[计数器]; 状态向量[计数器] = 状态向量[ (密钥[计数器 % 密钥长度] + 状态向量[计数器]) % 256]; 状态向量[ (密钥[计数器 % 密钥长度] + 状态向量[计数器]) % 256] = 临时交换值; } } /* RC4加密/解密算法 */ void RC4 (文本型 *输入,文本型 *输出,整数型 输入长度,文本型 *状态向量) { 整数型 计数器1 = 0, 计数器2 = 0, 计数器3; /* 循环计数器 */ 文本型 临时交换值; /* 用于交换状态向量值的临时变量 */
for (计数器3 = 0; 计数器3 < 输入长度; 计数器3++) { 计数器1 = (计数器1 + 1) % 256; 计数器2 = (状态向量[计数器1] + 计数器2) % 256; 临时交换值 = 状态向量[计数器1]; 状态向量[计数器1] = 状态向量[计数器2]; 状态向量[计数器2] = 临时交换值; 输出[计数器3] = 输入[计数器3] ^ 状态向量[ (状态向量[计数器1] + 状态向量[计数器2]) % 256]; } } 整数型 main () { 文本型 密钥[] = "密钥"; /* 加密密钥 */ 文本型 输入[] = "明文"; /* 待加密数据 */ 文本型 输出[sizeof (输入)]; /* 加密后的数据 */ 文本型 状态向量[256]; /* 状态向量 */
/* 调用密钥调度算法 */ 密钥初始化 (密钥,状态向量,sizeof (密钥));
/* 调用RC4加密算法 */ RC4 (输入,输出,sizeof (输入),状态向量);
printf ("加密后的数据: "); for (int i = 0; i < sizeof (输出); i++) printf ("%02X",输出[i]); printf ("\n");
return 0; }
|
评分
-
查看全部评分
|