#include <iostream>
#include <Windows.h>
#include <ShlObj.h>
#include <Shlwapi.h> #pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Shlwapi.lib") DWORD align(DWORD size, DWORD align, DWORD addr) {
if (!(size % align))
return addr + size;
return addr + (size / align + 1) * align;
} int main(int argc, char* argv[])
{
/*if (argc < 3)
{
std::cout << "Argomenti insufficienti.\n";
return 0;
}*/ HANDLE FirstFile = CreateFileA("Test_Hello World.exe", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); // File to read data from
if (FirstFile == INVALID_HANDLE_VALUE)
{
std::cout << "Impossibile aprire il file passato come primo argomento.\n";
return 0;
} HANDLE SecFile = CreateFileA("Test_Hello World.exe", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); // File to write the read data in
if (SecFile == INVALID_HANDLE_VALUE)
{
std::cout << "Impossibile aprire il file passato come secondo argomento.\n";
return 0;
} DWORD FirstFS = GetFileSize(FirstFile, 0); // First file dimension
DWORD SecondFS = GetFileSize(SecFile, 0); // Second file dimension BYTE* FirstFB = (BYTE*)VirtualAlloc(NULL, FirstFS, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Allocates memory for the first file
BYTE* SecondFB = (BYTE*)VirtualAlloc(NULL, SecondFS, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Allocates memory for the second file DWORD BytesRead = 0;
DWORD BytesWritten = 0; if (bool Read = ReadFile(FirstFile, FirstFB, FirstFS, &BytesRead, NULL) == FALSE) // Reads the first file
{
std::cout << "Impossibile leggere primo file.\n";
return 0;
}
else
{
std::cout << "Letti " << BytesRead << " dal primo file.\n";
BytesRead = 0;
} if (bool Read = ReadFile(SecFile, SecondFB, SecondFS, &BytesRead, NULL) == FALSE) // Reads the second file
{
std::cout << "Impossibile leggere secondo file.\n";
return 0;
}
else
{
std::cout << "Letti " << BytesRead << " bytes dal secondo file.\n";
BytesRead = 0;
} /*
*
* The code is problematic beyond this point!
*
* SecondFB = Pointer to the second file's data buffer that needs to be modified by adding the new section.
* FirstFB = Pointer to the first file's data buffer that will be written inside the ".sdata" section.
* Both of them have been loaded in memory using VirtualAlloc.
*
* Ask me anything for further info and many, many thanks :D */ // Here I add a new section to the second file. PIMAGE_DOS_HEADER sIDH = (IMAGE_DOS_HEADER*)SecondFB;
PIMAGE_NT_HEADERS sINH = (IMAGE_NT_HEADERS*)(SecondFB + sIDH->e_lfanew);
PIMAGE_FILE_HEADER sIFH = (PIMAGE_FILE_HEADER)(SecondFB + sIDH->e_lfanew + sizeof(DWORD));
PIMAGE_OPTIONAL_HEADER sIOH = (PIMAGE_OPTIONAL_HEADER)(SecondFB + sIDH->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER));
PIMAGE_SECTION_HEADER sISH = (PIMAGE_SECTION_HEADER)(SecondFB + sIDH->e_lfanew + sizeof(IMAGE_NT_HEADERS)); // Here I name the new section inside the file
ZeroMemory(&sISH[sIFH->NumberOfSections], sizeof(IMAGE_SECTION_HEADER));
CopyMemory(sISH[sIFH->NumberOfSections].Name, ".scode", 8); /*
0xE00000E0 = IMAGE_SCN_MEM_WRITE |
IMAGE_SCN_CNT_CODE |
IMAGE_SCN_CNT_UNINITIALIZED_DATA |
IMAGE_SCN_MEM_EXECUTE |
IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_READ */ // Here all the required information gets filled in
sISH[sIFH->NumberOfSections].VirtualAddress = align(sISH[sIFH->NumberOfSections - 1].Misc.VirtualSize, sIOH->SectionAlignment, sISH[sIFH->NumberOfSections - 1].VirtualAddress);
sISH[sIFH->NumberOfSections].SizeOfRawData = align(FirstFS, sIOH->SectionAlignment, 0);
sISH[sIFH->NumberOfSections].Misc.VirtualSize = align(FirstFS, sIOH->SectionAlignment, 0);
sISH[sIFH->NumberOfSections].PointerToRawData = align(sISH[sIFH->NumberOfSections - 1].SizeOfRawData, sIOH->FileAlignment, sISH[sIFH->NumberOfSections - 1].PointerToRawData);
sISH[sIFH->NumberOfSections].Characteristics = 0xE00000E0; // Here the changes are written to the second file
SetFilePointer(SecFile, sISH[sIFH->NumberOfSections].PointerToRawData + sISH[sIFH->NumberOfSections].SizeOfRawData, NULL, FILE_BEGIN);
SetEndOfFile(SecFile); sIOH->SizeOfImage = sISH[sIFH->NumberOfSections].VirtualAddress + sISH[sIFH->NumberOfSections].Misc.VirtualSize;
sIFH->NumberOfSections += 1;
SetFilePointer(SecFile, 0, NULL, FILE_BEGIN); BytesWritten = 0; bool W = WriteFile(SecFile, SecondFB, SecondFS, &BytesWritten, NULL); if (W == FALSE)
{
std::cout << "Impossibile aggiungere sezione alla stub.\n";
return 0;
}
else
{
std::cout << "Scritti " << BytesWritten << " bytes nella stub. (Aggiunta nuova sezione.)\n";
BytesWritten = 0;
} // Here I write the data inside the new section
SetFilePointer(SecFile, sISH[sIFH->NumberOfSections - 1].PointerToRawData, 0, FILE_BEGIN);
if (bool Write = WriteFile(SecFile, FirstFB, FirstFS, &BytesWritten, NULL) == FALSE)
{
std::cout << "Impossibile aggiungere sezione alla stub.\n";
}
else
{
std::cout << "Scritti " << BytesWritten << " bytes nella stub.\n";
BytesWritten = 0;
} // Here I close all the handles VirtualFree(FirstFB, FirstFS, MEM_RELEASE);
CloseHandle(FirstFile); VirtualFree(SecondFB, SecondFS, MEM_RELEASE);
CloseHandle(SecFile); std::cout << "Binding completato.\n"; return 0;
}

win32 - PE Executable and section inject的更多相关文章

  1. 深入理解 Win32 PE 文件格式

    深入理解 Win32 PE 文件格式 Matt Pietrek 这篇文章假定你熟悉C++和Win32. 概述 理解可移植可执行文件格式(PE)可以更好地了解操作系统.如果你知道DLL和EXE中都有些什 ...

  2. 深入理解 Win32 PE 文件格式 Matt Pietrek(慢慢体会)

    这篇文章假定你熟悉C++和Win32. 概述 理解可移植可执行文件格式(PE)可以更好地了解操作系统.如果你知道DLL和EXE中都有些什么东西,那么你就是一个知识渊博的程序员.这一系列文章的第一部分, ...

  3. 《Peering Inside the PE: A Tour of the Win32 Portable Executable File Format》阅读笔记二

    Common Sections The .text section is where all general-purpose code emitted by the compiler or assem ...

  4. PE Header and Export Table for Delphi

    Malware Analysis Tutorial 8: PE Header and Export Table 2. Background Information of PE HeaderAny bi ...

  5. The Portable Executable File Format from Top to Bottom(每个结构体都非常清楚)

    The Portable Executable File Format from Top to Bottom Randy KathMicrosoft Developer Network Technol ...

  6. 利用PE数据目录的导入表获取函数名及其地址

    PE文件是以64字节的DOS文件头开始的(IMAGE_DOS_HEADER),接着是一段小DOS程序,然后是248字节的 NT文件头(IMAGE_NT_HEADERS),NT的文件头位置由IMAGE_ ...

  7. 深入学习PE文件(转)

    PE文件是Win32的原生文件格式.每一个Win32可执行文件都遵循PE文件格式.对PE文件格式的了解可以加深你对Win32系统的深入理解. 一. 基本结构. 上图便是PE文件的基本结构.(注意:DO ...

  8. 深入剖析PE文件

    不赖猴的笔记,转载请注明出处. 深入剖析PE文件 PE文件是Win32的原生文件格式.每一个Win32可执行文件都遵循PE文件格式.对PE文件格式的了解可以加深你对Win32系统的深入理解. 一.   ...

  9. Load PE from memory(反取证)(未完)

      Article 1:Loading Win32/64 DLLs "manually" without LoadLibrary() The most important step ...

  10. 动态加载并执行Win32可执行程序

    本文所贴出的PoC代码将告诉你如何通过CreateProcess创建一个傀儡进程(称之为可执行程序A),并把dwCreationFlags设置为CREATE_SUSPENDED,然后把另一个可执行程序 ...

随机推荐

  1. [转帖]s3fs把 s3-like 对象存储挂载到本地

    s3fs把 s3-like 对象存储挂载到本地 s3fs把 s3-like 对象存储挂载到本地 s3fs-fuse 是一个采用 c++ 开发的开源应用,它的作用是可以将 AWS S3 以及兼容 S3 ...

  2. [转帖]Kafka-LEO和HW概念及更新流程

    https://www.cnblogs.com/youngchaolin/p/12641463.html 目录 LEO&HW基本概念 LEO&HW更新流程 LEO HW 更新流程示例分 ...

  3. [转帖]linux性能优化-内存回收

    linux文件页.脏页.匿名页 缓存和缓冲区,就属于可回收内存.它们在内存管理中,通常被叫做文件页(File-backed Page). 通过内存映射获取的文件映射页,也是一种常见的文件页.它也可以被 ...

  4. [转帖]浅谈Armv8-A处理器

    https://www.elecfans.com/emb/dsp/202208291886182.html 众所周知,ARM是一家设计并授权处理器和相应IP(比如互连总线,中断处理器,图像处理器等等) ...

  5. redis 6源码解析之 dict

    edis源码的dict.c主要实现了基于hash表的操作,如增删改查,对哈希表大小的扩容和缩容,以及对哈希表的rehash和增量rehash等.在源码的dictScan函数中,非常巧妙精美地实现了对哈 ...

  6. 庖丁解牛:最全babel-plugin-import源码详解

    庖丁解牛:最全 babel-plugin-import 源码详解 序言:在用 babel-plugin 实现按需加载一文中笔者用作用域链思路实现了按需加载组件.此思路是统一式处理,进入 ImportD ...

  7. 数据结构与算法 第一章(48课时课程笔记)Data Structure and Algorithms

    数据结构基础知识 数据(Data):是对信息的一种符号表示.在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称.数据元素(Data Element):是数据的基本单位,在计算机程序中 ...

  8. 解锁前端新潜能:如何使用 Rust 锈化前端工具链

    ​ 前言 近年来,Rust的受欢迎程度不断上升.首先,在操作系统领域,Rust 已成为 Linux 内核官方认可的开发语言之一,Windows 也宣布将使用 Rust 来重写内核,并重写部分驱动程序. ...

  9. 使用Ant Design Vue的select搜索框出现的问题

    Select 选择器进行搜索 <template> <div> <a-form-item label="分类:"> <a-select p ...

  10. elementui中表格表头设置背景色

    参考的地址: https://www.cnblogs.com/lljun/p/11551128.html 今天在设置表格的表头的时候,我通过类的时候 发现无法设置表格的表头设置不了颜色: 经过查找:原 ...