修改DLL文件,注入C#代码

因需要,修改两个DLL文件(C#写),没有C#源代码。网上查找方法,了解到:

高级语言源程序经过编译变成可执行文件,反编译就是逆过程。但是通常不能把可执行文件变成高级语言源代码,只能转换成汇编程序。.NET程序的反编译非常 非常简单,简单到任何一本关于.NET基础的书都会或多或少的提一下。.NET程序反编译后是MSIL(微软中间语言)而不是汇编语言,这也是.NET程 序语言无关性和平台无关性的基础。反编译的工具有微软自带的ildasm,也有非常牛的Reflector。

使用Reflector加上Reflexil插件,注入C#代码,使用.Net Reflector的Reflector.FileDisassembler和FileGenerator都能导出C#类等源代码,甚至还能生成一个工程文件,但与源代码还是有些区别,DLL重新编译后,头文件等信息被修改,无法直接使用。

看到源代码,了解大概如何修改,却不知道如何往原DLL注入一段C#代码,看到Reflexil插件的使用,能修改IL中的指令,试着修改了其中SQL值,保存成功了,DLL就被修改了。但往其中一个类加入一个方法,却不是那么容易,完全看不懂IL。

网上查到:

ILDASM教程

虚拟CPU
对.NET程序来说,.NET CLR在功能上就如同一块虚拟的CPU,它执行IL代码、操作数据。CLR和真实的CPU类似之处在于它们都不直接操作内存中的变量而是使用程序变量的临 时拷贝,CLR把这些程序变量存放在堆栈上。从内存拷贝某个变量到堆栈的行为称做装载(loading),而从堆栈拷回某个变量到内存的行为则被称做存储 (storing)。

类似于windows原生环境下的asm和dasm,.NET环境下,微软提供了这两个“瑞士军刀”般的工具。
感觉它们2个就好比庖丁手下的尖刀一样,可以对.NET程序进行任意解剖,分析,而且解剖,分析完后又可以再重新组装,运行,呵呵,真是游刃有余啊!
ilasm usage:
Usage: ilasm [Options] <sourcefile> [Options]

Options:
/LISTING                Type a formatted list file
/NOLOGO                 Don't type the logo
/QUIET                  Don't report assembly progress
/DLL                    Compile to .dll
/EXE                    Compile to .exe (default)
/DEBUG                  Include debug information
/CLOCK                  Measure and report compilation times
/RESOURCE=<res_file>    Link the specified resource file (*.res)
                        into resulting .exe or .dll
/OUTPUT=<targetfile>    Compile to file with specified name
                        (user must provide extension, if any)
/KEY=<keyfile>          Compile with strong signature
                        (<keyfile> contains private key)
/KEY=@<keysource>       Compile with strong signature
                        (<keysource> is the private key source name)
/SUBSYSTEM=<int>        Set Subsystem value in the NT Optional header
/FLAGS=<int>            Set CLR ImageFlags value in the CLR header
/ALIGNMENT=<int>        Set FileAlignment value in the NT Optional header
/BASE=<int>             Set ImageBase value in the NT Optional header

Key may be '-' or '/'
Options are recognized by first 3 characters
Default source file extension is .IL
ildasm usage:
用法: ildasm [options] <file_name> [options]

用于输出重定向的选项:
  /OUT=<file name>    直接输出到文件而不是 GUI。
  /TEXT               直接输出到控制台窗口而不是 GUI。

用于 GUI 或文件/控制台输出的选项(仅限于 EXE 和 DLL 文件):
  /BYTES              将实际字节(十六进制)显示为指令注释。
  /RAWEH              以原始形式显示异常处理子句。
  /TOKENS             显示类和成员的元数据标记。
  /SOURCE             将原始源行显示为注释。
  /LINENUM            包括对原始源行的引用。
  /VISIBILITY=<vis>[+<vis>...]    仅反汇编具有指定
          可见性的项。(<vis> = PUB | PRI | FAM | ASM | FAA | FOA | PSC)
  /PUBONLY            仅反汇编公共项(与 /VIS=PUB 相同)。
  /QUOTEALLNAMES      将所有名称用单引号括起来。
  /NOBAR              取消反汇编进度栏窗口弹出。

下列选项只对文件/控制台输出有效:
用于 EXE 和 DLL 文件的选项:
  /UTF8               对输出使用 UTF-8 编码(默认为 ANSI)。
  /UNICODE            对输出使用 UNICODE 编码。
  /NOIL               取消 IL 汇编程序代码输出。
  /HEADER             在输出中包括文件头信息。
  /ITEM=<class>[::<method>[(<sig>)]  只反汇编指定的项

  /ALL        /HEADER、/BYTES、/TOKENS 的组合

选项的关键字为“-”或“/”,通过前三个字符识别选项

示例: ildasm /tok /byt myfile.exe /out=myfile.il
给出以前对于1个dll文件进行分析,修改后,又重新编译的命令行步骤:
1.ildasm Web.dll /all /out=Web.il
2.用文本编辑器修改Web.il中的il代码
3.ilasm Web.il /dll /out=Web.dll  (还可以加上 /res=Web.res)
就这样,dll——>il——>dll,再配合上Reflector.net使用,将DLL修改了一小段,又保存DLL,与原先差不多。
ildasm myfile.dll /all /out=myfile.il
ilasm myfile.il /dll /out=myfile.dll
关于反编译和编译,确实了解得不多。第一次看IL文件,用Google和百度到处查询资料,瞎子摸象。百度跟谷歌比起来,光搜索功能就差了许多,不怪我们崇洋媚外,跟谷歌比起来,百度有时用起来像山寨货。(这两天搜索的感觉)

转载于:https://www.cnblogs.com/toyman_1298/archive/2011/01/06/1927058.html

C++ DLL (动态链接库) 远程注入C# 程序通常涉及使用 P/Invoke (Platform Invoke) 或 COM Interop 来调用 C++ 函数。以下是基本的概念和一个简单的例子: 首先,在C++创建一个DLL(例如MyDll.dll),包含一个可以被C#调用的函数: ```cpp // MyDll.h #pragma once extern "C" __declspec(dllexport) void InjectCode(char* code); ``` ```cpp // MyDll.cpp #include "MyDll.h" #include <windows.h> void InjectCode(char* code) { // 实现代码注入的部分,这里只是一个示例,实际可能会涉及到内存操作和执行汇编指令 RemoteThreadCreationInfo info; info.ThreadStartAddress = reinterpret_cast<void*>(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "VirtualProtect")); // 示例地址,替换为你需要执行的实际地址 info.ThreadStackSize = 0x1000; // 4KB堆栈大小 CreateRemoteThread(GetCurrentProcess(), NULL, NULL, (LPTHREAD_START_ROUTINE)code, (LPVOID)NULL, 0, NULL); // 将C#传递的代码作为远程线程启动 } ``` 然后在C#通过P/Invoke调用这个函数: ```csharp using System; using System.Runtime.InteropServices; class Program { [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)] static extern void InjectCode([MarshalAs(UnmanagedType.LPStr)] string code); static void Main(string[] args) { const string csharpCode = @" // 这里是你要注入C#代码片段 Assembly asm = Assembly.GetExecutingAssembly(); MethodBase method = asm.EntryPoint; method.Invoke(null, null); "; byte[] codeBuffer = Encoding.UTF8.GetBytes(csharpCode); InjectCode(codeBuffer); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值