Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
l-iberty committed Sep 25, 2019
1 parent b292840 commit 6323321
Show file tree
Hide file tree
Showing 19 changed files with 624 additions and 0 deletions.
8 changes: 8 additions & 0 deletions DLL_Injection2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 通过修改PE文件实现DLL注入
## 整体设计
1. 将原来的`IDT`拷贝到最后一个节的末尾
2. 在新的IDT末尾为目标DLL添加一个`IMAGE_IMPORT_DIRECTORY`结构体
3. 在新的IDT后面依次放置目标DLL的`INT``IAT`、目标DLL的文件名、一个`WORD`(两个字节)的`Hint`和目标DLL的导出函数的名字(目标DLL必须至少有一个导出函数,否则这个DLL不会被加载)
4. 上述所有数据附加到最后一个节的末尾,结构如下:

![](images/1.png)
Binary file added DLL_Injection2/images/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added DLL_Injection2/images/1.vsdx
Binary file not shown.
2 changes: 2 additions & 0 deletions DLL_Injection2/src/DLLInjection2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*Debug
*Release
34 changes: 34 additions & 0 deletions DLL_Injection2/src/DLLInjection2/DLLInjection2.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLInjection2", "DLLInjection2\DLLInjection2.vcxproj", "{41425E4F-E5B9-4E08-90B1-F358AA95F41B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testApp", "testApp\testApp.vcxproj", "{EB677F14-2366-4068-A69B-18C49B4578F0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdll", "testdll\testdll.vcxproj", "{DA066F8D-2629-4BCB-A6DC-BB5E900179C9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{41425E4F-E5B9-4E08-90B1-F358AA95F41B}.Debug|Win32.ActiveCfg = Debug|Win32
{41425E4F-E5B9-4E08-90B1-F358AA95F41B}.Debug|Win32.Build.0 = Debug|Win32
{41425E4F-E5B9-4E08-90B1-F358AA95F41B}.Release|Win32.ActiveCfg = Release|Win32
{41425E4F-E5B9-4E08-90B1-F358AA95F41B}.Release|Win32.Build.0 = Release|Win32
{EB677F14-2366-4068-A69B-18C49B4578F0}.Debug|Win32.ActiveCfg = Debug|Win32
{EB677F14-2366-4068-A69B-18C49B4578F0}.Debug|Win32.Build.0 = Debug|Win32
{EB677F14-2366-4068-A69B-18C49B4578F0}.Release|Win32.ActiveCfg = Release|Win32
{EB677F14-2366-4068-A69B-18C49B4578F0}.Release|Win32.Build.0 = Release|Win32
{DA066F8D-2629-4BCB-A6DC-BB5E900179C9}.Debug|Win32.ActiveCfg = Debug|Win32
{DA066F8D-2629-4BCB-A6DC-BB5E900179C9}.Debug|Win32.Build.0 = Debug|Win32
{DA066F8D-2629-4BCB-A6DC-BB5E900179C9}.Release|Win32.ActiveCfg = Release|Win32
{DA066F8D-2629-4BCB-A6DC-BB5E900179C9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{41425E4F-E5B9-4E08-90B1-F358AA95F41B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>DLLInjection2</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="file_mapping.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="pe_file_helper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="file_mapping.h" />
<ClInclude Include="pe_file_helper.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pe_file_helper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="file_mapping.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pe_file_helper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="file_mapping.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
44 changes: 44 additions & 0 deletions DLL_Injection2/src/DLLInjection2/DLLInjection2/file_mapping.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <assert.h>
#include "file_mapping.h"

FileMapping::FileMapping(PCWSTR pszFileName)
:m_hFile(INVALID_HANDLE_VALUE),
m_hFileMapping(INVALID_HANDLE_VALUE),
m_pFileMappingBase(NULL)
{
m_hFile = ::CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
assert(m_hFile != INVALID_HANDLE_VALUE);

DWORD dwFileSize = ::GetFileSize(m_hFile, NULL);
m_hFileMapping = ::CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0,
dwFileSize + kExtraBlockSize, pszFileName);
assert(m_hFileMapping != INVALID_HANDLE_VALUE);

m_pFileMappingBase = ::MapViewOfFile(m_hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
assert(m_pFileMappingBase != NULL);
}

PVOID FileMapping::GetFileMappingBase()
{
return m_pFileMappingBase;
}

BOOL FileMapping::Flush()
{
assert(m_pFileMappingBase != NULL);
return ::FlushViewOfFile(m_pFileMappingBase, 0);
}

FileMapping::~FileMapping()
{
if (m_pFileMappingBase != NULL) {
::UnmapViewOfFile(m_pFileMappingBase);
m_pFileMappingBase = NULL;
}
if (m_hFileMapping != INVALID_HANDLE_VALUE) {
::CloseHandle(m_hFileMapping);
}
if (m_hFile != INVALID_HANDLE_VALUE) {
::CloseHandle(m_hFile);
}
}
20 changes: 20 additions & 0 deletions DLL_Injection2/src/DLLInjection2/DLLInjection2/file_mapping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef FILE_MAPPING_H
#define FILE_MAPPING_H

#include <Windows.h>

class FileMapping
{
public:
FileMapping(PCWSTR pszFileName);
~FileMapping();
PVOID GetFileMappingBase();
BOOL Flush();
private:
const DWORD kExtraBlockSize = 4096;
HANDLE m_hFile;
HANDLE m_hFileMapping;
PVOID m_pFileMappingBase;
};

#endif /* FILE_MAPPING_H */
9 changes: 9 additions & 0 deletions DLL_Injection2/src/DLLInjection2/DLLInjection2/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <Windows.h>
#include <iostream>
#include "pe_file_helper.h"

int main()
{
PeFileHelper pe_file(TEXT("testApp.exe"));
pe_file.InjectDll("testdll.dll", "dummy");
}
114 changes: 114 additions & 0 deletions DLL_Injection2/src/DLLInjection2/DLLInjection2/pe_file_helper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include "pe_file_helper.h"

PeFileHelper::PeFileHelper(LPCWSTR pszFileName):m_FileMapping(pszFileName)
{
m_pFileBase = m_FileMapping.GetFileMappingBase();
assert(m_pFileBase != NULL);
m_pDosHeader = (PIMAGE_DOS_HEADER)m_pFileBase;
m_pNtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)m_pFileBase + m_pDosHeader->e_lfanew);
}

PeFileHelper::~PeFileHelper()
{
m_FileMapping.Flush();
}

void PeFileHelper::SeekToNtHeaders()
{
m_pCurrentFilePointer = (PCHAR)m_pNtHeaders;
}

void PeFileHelper::SeekToSectionHeader()
{
m_pCurrentFilePointer = (PCHAR)m_pNtHeaders + sizeof(IMAGE_NT_HEADERS);
}

void PeFileHelper::SeekToImportDirectoryTable()
{
DWORD importDirectoryTableRva = m_pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
m_pCurrentFilePointer = (PCHAR)m_pFileBase + Rva2Offset(importDirectoryTableRva);
}

void PeFileHelper::InjectDll(PCSTR pszFileName, PCSTR pszProcName)
{
DWORD numSections = m_pNtHeaders->FileHeader.NumberOfSections;
SeekToSectionHeader();
PIMAGE_SECTION_HEADER pFirstSectionHeader = (PIMAGE_SECTION_HEADER)m_pCurrentFilePointer;
PIMAGE_SECTION_HEADER pLastSectionHeader = pFirstSectionHeader + numSections - 1;
PCHAR pLastSectionStart = (PCHAR)m_pFileBase + pLastSectionHeader->PointerToRawData;
PCHAR pLastSectionEnd = pLastSectionStart + pLastSectionHeader->SizeOfRawData;

SeekToImportDirectoryTable();
PIMAGE_IMPORT_DESCRIPTOR pFirstIDTEntry = (PIMAGE_IMPORT_DESCRIPTOR)m_pCurrentFilePointer;
DWORD oldIDTSize = m_pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
DWORD newIDTSize = oldIDTSize + sizeof(IMAGE_IMPORT_DESCRIPTOR);
DWORD lastSectionSizeIncrement = newIDTSize + // IDT, new entry included
sizeof(void*) * 2 + // INT - one entry for pszProcName, one entry for NULL
sizeof(void*) * 2 + // IAT - one entry for pszProcName, one entry for NULL
strlen(pszFileName) + 1 +
sizeof(WORD) + strlen(pszProcName) + 1;

PCHAR p = pLastSectionEnd;
PCHAR pINT, pIAT, ppszFileName, ppszProcName;
memcpy(p, pFirstIDTEntry, oldIDTSize);
p += oldIDTSize;
memset(p, 0, sizeof(IMAGE_IMPORT_DESCRIPTOR)); // for new IDT entry
p += sizeof(IMAGE_IMPORT_DESCRIPTOR);
pINT = p;
pIAT = p + sizeof(void*) * 2;
memset(p, 0, sizeof(void*) * 8); // for INT and IAT
p += sizeof(void*) * 8;
ppszFileName = p;
strcpy(p, pszFileName);
p += strlen(pszFileName) + 1;
memset(p, 0, sizeof(WORD));
ppszProcName = p;
p += sizeof(WORD);
strcpy(p, pszProcName);

PIMAGE_IMPORT_DESCRIPTOR pNewIDTEntry = (PIMAGE_IMPORT_DESCRIPTOR)
(pLastSectionEnd + oldIDTSize - sizeof(IMAGE_IMPORT_DESCRIPTOR)); // oldIDTSize包含了最后一个空结构体的大小, 所以要减回去

// 填充Import Name Table(INT)
*(DWORD*)pINT = pLastSectionHeader->VirtualAddress + (ppszProcName - pLastSectionStart);
// 填充Import Address Table(IAT)
*(DWORD*)pIAT = *(DWORD*)pINT;
// RVA to INT
pNewIDTEntry->OriginalFirstThunk = pLastSectionHeader->VirtualAddress + (pINT - pLastSectionStart);
// RVA to DLL name(pszFileName)
pNewIDTEntry->Name = pLastSectionHeader->VirtualAddress + (ppszFileName - pLastSectionStart);
// RVA to Import Address Table(IAT)
pNewIDTEntry->FirstThunk = pLastSectionHeader->VirtualAddress + (pIAT - pLastSectionStart);

// 修改NT Headers中记录IDT的RVA和Size, 使其对应新的IDT
m_pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress =
pLastSectionHeader->VirtualAddress + pLastSectionHeader->SizeOfRawData;
m_pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = newIDTSize;

// 将最后一个节扩大 lastSectionSizeIncrement 个字节
DWORD fileAlignment = m_pNtHeaders->OptionalHeader.FileAlignment;
DWORD x = pLastSectionHeader->SizeOfRawData + lastSectionSizeIncrement;
pLastSectionHeader->SizeOfRawData = (x + fileAlignment - 1) / fileAlignment * fileAlignment;
pLastSectionHeader->Misc.VirtualSize = pLastSectionHeader->SizeOfRawData;
pLastSectionHeader->Characteristics |= IMAGE_SCN_MEM_WRITE;

return;
}

DWORD PeFileHelper::Rva2Offset(DWORD dwRva)
{
DWORD numSections = m_pNtHeaders->FileHeader.NumberOfSections;
SeekToSectionHeader();
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)m_pCurrentFilePointer;

for (DWORD i = 0; i < numSections; i++) {
DWORD rvaStart = pSectionHeader->VirtualAddress;
DWORD rvaEnd = rvaStart + pSectionHeader->SizeOfRawData;
if (dwRva >= rvaStart && dwRva <= rvaEnd) {
DWORD dwRva2 = dwRva - rvaStart;
return pSectionHeader->PointerToRawData + dwRva2;
}
pSectionHeader++;
}
return 0;
}
Loading

0 comments on commit 6323321

Please sign in to comment.