吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2325|回复: 15
上一主题 下一主题
收起左侧

[其他原创] 原创首发,不调用CreateProcess,启动Win32程序

[复制链接]
跳转到指定楼层
楼主
aswcy815174418 发表于 2021-11-27 20:23 回帖奖励
本帖最后由 aswcy815174418 于 2021-11-27 20:48 编辑

大体思路:拉伸→修复导入表→修复重定位表→创建线程(定义winmain函数指针,并传入参数调用),效果图在最底下


写这个源码的缘由: 前几天面试了一家安全公司,面试官问我,内核重载后,全局变量怎么处理,我想了想

不是修复重定位表就可以了嘛?后来仔细想了想,重定位只是修复了全局变量的地址,并没有初始化内核重载后,
全局变量所存的值,后来研究了下,什么时候全局变量会初始化
一丶编译前就赋了初始值,没有的话默认就赋值为0
二丶从main函数开始初始化(并没有准确的说,就是在main函数初始化,也可能是main函数调了其它函数进行初始化的)
内核文件,经过研究发现,全局变量用的是第二种进行初始化,如果把内核文件,拉伸,重定位,修复导入表
如果知道内核main函数参数,用文中的方法,可能会解决掉全局变量的处理(意味着,可以不用老内核的数据,直接用新内核数据)

测试用到的文件: 点我下载

// LoadProcess.cpp : Defines the entry point for the console application.
//

#include "windows.h"
#include "stdio.h"
//隐藏控制台
//#pragma   comment(linker,"/subsystem:\"windows\"  /entry:\"mainCRTStartup\""   ) 

//重定位
BOOL modify_base_table(TCHAR* imagebuffer, DWORD new_imagebasse);

DWORD ThreadProc(PVOID Parameter) {

        typedef BOOL(APIENTRY *CallMain)(HMODULE hModule,
                DWORD  ul_reason_for_call,
                LPVOID lpReserved
                );
        PIMAGE_DOS_HEADER h_dos_header = (PIMAGE_DOS_HEADER)Parameter;//dos头
        PIMAGE_NT_HEADERS hNt = (PIMAGE_NT_HEADERS)((DWORD)Parameter + h_dos_header->e_lfanew);//nt头

        DWORD OEP = hNt->OptionalHeader.AddressOfEntryPoint + (DWORD)Parameter;

        CallMain p = OEP;

        p((DWORD)Parameter, 1, 0);

        return 0;
}

int main(int argc, char* argv[]) {
        DWORD size_file = 0;//文件大小
        char* filebuffer = NULL;//filebuffer
        char* imagebuffer = NULL;//imagebase
        DWORD sizeofimage = NULL;//文件的sizeofimage
        DWORD number_section = 0;//节的数量
        DWORD size_all_headers = 0;//所有头的大小

        //用fopen打开一个进程
        FILE* h_file = fopen("C:\\win32.exe", "rb+");
        DWORD DD = GetLastError();
        if (NULL == h_file) {
                printf("用fopen打开文件失败,请检查文件地址是否错误\n");
                return -1;
        }
        //得到其大小
        fseek(h_file, 0, SEEK_END);
        size_file = ftell(h_file);
        fseek(h_file, 0, SEEK_SET);
        //为其申请内存
        filebuffer = (char*)malloc(size_file);
        //初始化内存
        memset(filebuffer, 0, size_file);
        if (NULL == filebuffer) {
                printf("申请filebuffer失败\n");
                return -1;
        }
        //文件写入内存
        fread(filebuffer, 1, size_file, h_file);
        if (IMAGE_DOS_SIGNATURE != *(short*)filebuffer) {
                printf("该文件不是PE文件\n");
                return -1;
        }
        //得到其sizeofimage
        PIMAGE_DOS_HEADER hDos = (PIMAGE_DOS_HEADER)filebuffer;//dos头
        PIMAGE_NT_HEADERS hNt = (PIMAGE_NT_HEADERS)(filebuffer + hDos->e_lfanew);//nt头

        if (IMAGE_NT_SIGNATURE != hNt->Signature) {
                printf("该文件不是PE文件\n");
                return -1;
        }
        sizeofimage = hNt->OptionalHeader.SizeOfImage;
        //拉伸
        //申请内存
        imagebuffer = (char*)malloc(sizeofimage);
        if (NULL == imagebuffer) {
                printf("申请imagebuffer失败\n");
                return -1;
        }

        //初始化内存
        memset(imagebuffer, 0, sizeofimage);
        //得到节表
        PIMAGE_SECTION_HEADER SectionArr = (PIMAGE_SECTION_HEADER)((DWORD)hNt + 24 + hNt->FileHeader.SizeOfOptionalHeader);
        //得到节的数量
        number_section = hNt->FileHeader.NumberOfSections;
        //得到所有头的大小
        size_all_headers = hNt->OptionalHeader.SizeOfHeaders;
        //复制头
        memcpy(imagebuffer, filebuffer, size_all_headers);
        //复制节区
        while (number_section--) {
                DWORD VirtualAddress = 0;
                DWORD PointerToRawData = 0;
                DWORD SizeOfRawData = 0;
                //得到VirtualAddress
                VirtualAddress = SectionArr->VirtualAddress;
                //得到PointerToRawData
                PointerToRawData = SectionArr->PointerToRawData;
                //得到SizeOfRawData
                SizeOfRawData = SectionArr->SizeOfRawData;
                memcpy(imagebuffer + VirtualAddress, filebuffer + PointerToRawData, SizeOfRawData);
                SectionArr++;
        }

        //修复iat表
        //得到导入表
        PIMAGE_IMPORT_DESCRIPTOR ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)(imagebuffer + hNt->OptionalHeader.DataDirectory[1].VirtualAddress);
        while (0 != ImportTable->FirstThunk) {
                //得到dll名字
                char* dll_name = imagebuffer + ImportTable->Name;
                //得到iat表
                int* IatTable = (int*)(imagebuffer + ImportTable->FirstThunk);
                while (*IatTable) {
                        //判断最高位是不是1
                        if ((*IatTable) & 0x80000000) {
                                *IatTable = (DWORD)GetProcAddress(LoadLibrary(dll_name), (char*)((*IatTable) & 0x7FFFFFFF));
                                IatTable++;
                        } else {
                                //得到By_Name结构体
                                PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)(imagebuffer + *IatTable);
                                char* function_name = (char*)by_name->Name;
                                *IatTable = (DWORD)GetProcAddress(LoadLibrary(dll_name), function_name);
                                IatTable++;
                        }
                }
                ImportTable++;
        }

        //修复重定位表
        if (FALSE == modify_base_table((TCHAR*)imagebuffer, (DWORD)imagebuffer)) {
                printf("重定位失败\n");

                return -1;
        }

        //老属性
        DWORD old;
        //修改为可执行,可读可写
        VirtualProtect(imagebuffer, hNt->OptionalHeader.SizeOfImage, PAGE_EXECUTE_READWRITE, &old);

        //从OEP开始跑
        HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadProc, imagebuffer, 0, 0);

        WaitForSingleObject(hThread, -1);
        fclose(h_file);
        free(filebuffer);
        free(imagebuffer);
        return 0;
}

BOOL modify_base_table(TCHAR* imagebuffer, DWORD new_imagebasse) {
        DWORD imagebase = 0;
        //判断有没有重定位表
                //得到NT头
        PIMAGE_DOS_HEADER exe_f_dos_header = (PIMAGE_DOS_HEADER)imagebuffer;
        PIMAGE_NT_HEADERS exe_f_nt_header = (PIMAGE_NT_HEADERS)((DWORD)imagebuffer + (DWORD)exe_f_dos_header->e_lfanew);
        //得到imagebase
        imagebase = exe_f_nt_header->OptionalHeader.ImageBase;
        //得到重定位表
        PIMAGE_BASE_RELOCATION exe_f_base_relocation = (PIMAGE_BASE_RELOCATION)(imagebuffer + exe_f_nt_header->OptionalHeader.DataDirectory[5].VirtualAddress);
        //判断
        if (0 == exe_f_base_relocation->VirtualAddress && 0 == exe_f_base_relocation->SizeOfBlock) {
                return FALSE;
        }
        //修复
        while (0 != exe_f_base_relocation->VirtualAddress && 0 != exe_f_base_relocation->SizeOfBlock) {
                int* virtual_add = NULL;
                short value = 0;
                //得到要修复的数量
                DWORD number_of_modify = (exe_f_base_relocation->SizeOfBlock - 8) / 2;
                //得到要修复的位置
                short* adderss_of_modify = (short*)((DWORD)exe_f_base_relocation + 8);
                //开始
                while (number_of_modify--) {
                        value = *adderss_of_modify;
                        //判断最高位是不是3
                        if (value >> 12 == 3) {
                                //去掉前面的属性
                                value = value & 0x0FFF;
                                virtual_add = (int*)(imagebuffer + exe_f_base_relocation->VirtualAddress + value);
                                *virtual_add = *virtual_add - imagebase + new_imagebasse;
                        }
                        adderss_of_modify++;
                }
                //得到下一个块的地址
                exe_f_base_relocation = (PIMAGE_BASE_RELOCATION)((DWORD)exe_f_base_relocation + exe_f_base_relocation->SizeOfBlock);
        }
        //更改imagebase
        exe_f_nt_header->OptionalHeader.ImageBase = new_imagebasse;
        return TRUE;
}

效果图.png (322.13 KB, 下载次数: 1)

效果图

效果图

免费评分

参与人数 5威望 +1 吾爱币 +24 热心值 +4 收起 理由
Tonyha7 + 1 我很赞同!
arryboom + 2 + 1 我很赞同!
笙若 + 1 + 1 谢谢@Thanks!
xunidewangsheng + 1 我很赞同!
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

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

推荐
苏紫方璇 发表于 2021-11-28 17:11
想起来在哪里看到过类似的了,这个操作其他进程的,原理应该差不多
https://blog.csdn.net/xfgryujk/article/details/81360292
沙发
rogxo 发表于 2021-11-27 21:17
3#
nimeilai 发表于 2021-11-27 22:23
4#
CC000731 发表于 2021-11-27 22:28
这不是PE的知识么?
5#
 楼主| aswcy815174418 发表于 2021-11-27 22:33 |楼主
CC000731 发表于 2021-11-27 22:28
这不是PE的知识么?

就是PE知识
6#
非洲小白脸. 发表于 2021-11-28 04:14
易语言EXE没有重定位怎么办?
7#
xiaoshu1688 发表于 2021-11-28 07:59
涨知识了,不错。
8#
segasonyn64 发表于 2021-11-28 09:35
感谢,请问能否搞成支持X64的???
9#
asts 发表于 2021-11-28 10:01
今天又学习了一个新知识!!
10#
CD3 发表于 2021-11-28 10:04
支持原创
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-5-15 00:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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