C#调用系统API实现内存注入的代码

 
//首先导入命名空间 
using System.Runtime.InteropServices; 
/// <summary> 
/// 在指定进程的虚拟地址空间中保留或开辟一段区域..除非MEM_RESET被使用,否则将该内存区域初始化为0. 
/// </summary> 
/// <param name="process">需要在其中分配空间的进程的句柄.这个句柄必须拥有PROCESS_VM_OPERATION访问权限</param> 
/// <param name="pAddress">想要获取的地址区域.一般用NULL自动分配</param> 
/// <param name="size">要分配的内存大小.字节单位.注意实际分 配的内存大小是页内存大小的整数倍</param> 
/// <param name="type">内存分配的类型</param> 
/// <param name="protect">内存页保护</param> 
/// <returns>执行成功就返回分配内存的首地址,失败返回0。</returns> 
[DllImport("kernel32.dll")] //声明API函数 
public static extern int VirtualAllocEx(IntPtr process, int pAddress, int size, int type, int protect); 
/// <summary> 
/// 写入某一进程的内存区域。入口区必须可以访问,否则操作将失败 
/// </summary> 
/// <param name="process">进程句柄</param> 
/// <param name="baseAddress">要写的内存首地址</param> 
/// <param name="buffer">指向要写的数据的指针(数据当前存放地址)。</param> 
/// <param name="nSize">要写入的字节数。</param> 
/// <param name="lpNumberOfBytesWritten">实际数据的长度</param> 
/// <returns>非零表示成功,零表示失败</returns> 
[DllImport("kernel32.dll")] 
public static extern int WriteProcessMemory(IntPtr process, int baseAddress, string buffer, int nSize, int lpNumberOfBytesWritten); 
/// <summary> 
/// 检索指定的动态链接库(DLL)中的输出库函数地址 
/// </summary> 
/// <param name="hModule"> DLL模块句柄 包含此函数的DLL模块的句柄。LoadLibrary或者GetModuleHandle函数可以返回此句柄。</param> 
/// <param name="lpProcName">函数名 包含函数名的以NULL结尾的字符串,或者指定函数的序数值。如果此参数是一个序数值,它必须在一个字的底字节,高字节必须为0。</param> 
/// <returns>调用成功,返回DLL中的输出函数地址,调用失败,返回0。得到进一步的错误信息,调用函数GetLastError。</returns> 
[DllImport("kernel32.dll")] 
public static extern int GetProcAddress(int hModule, string lpProcName); 
/// <summary> 
/// 获取一个应用程序或动态链接库的模块句柄 
/// </summary> 
/// <param name="moduleName">指定模块名,这通常是与模块的文件名相同的一个名字</param> 
/// <returns>如执行成功成功,则返回模块句柄。零表示失败</returns> 
[DllImport("kernel32.dll")] 
public static extern int GetModuleHandleA(string moduleName); 
/// <summary> 
/// 创建一个在其它进程地址空间中运行的线程(也称:创建远程线程). 
/// </summary> 
/// <param name="process">目标进程的句柄</param> 
/// <param name="threadAttributes">指向线程的安全描述结构体的指针,一般设置为0,表示使用默认的安全级别</param> 
/// <param name="stackSize">线程堆栈大小,一般设置为0,表示使用默认的大小,一般为1M</param> 
/// <param name="startAddress">线程函数的地址</param> 
/// <param name="parameter">传给线程函数的参数</param> 
/// <param name="creationFlags">线程的创建方式(0表示线程创建后立即运行 CREATE_SUSPENDED 0x00000004以挂起方式创建 创建不会运行,直到调用 ResumeThread函数)</param> 
/// <param name="threadid">指向所创建线程句柄的指针,如果创建失败,该参数为0</param> 
/// <returns>如果调用成功,返回新线程句柄,失败返回0</returns> 
[DllImport("kernel32.dll")] 
public static extern int CreateRemoteThread(IntPtr process, int threadAttributes, int stackSize, int startAddress, int parameter, int creationFlags, int threadid); 

/// <summary> 
/// 根据进程名称获取进程 
/// </summary> 
/// <param name="ProcessName">进程名称</param> 
/// <returns></returns> 
public Process GetProcessByName(string ProcessName) 
{ 
//取得所有进程 
Process[] pname = Process.GetProcesses(); 
//遍历进程 
foreach (Process name in pname) 
{ 
//如果查找到进程名称 返回 
if (name.ProcessName.ToLower().IndexOf(ProcessName) != -1) 
return name; 
} 
return null; 
} 

public void killDll() 
{ 
string dllName = "c:\\text.dll"; 
int dlllength = dllName.Length + 1; 
//这里以记事本为例 
Process processName = GetProcessByName("notepad"); 
//如果查找到记事本进程,那么下面开始注入 
if (processName != null) 
{ 
//申请内存空间,执行成功就返回分配内存的首地址,不成功就是0。 
int baseaddress = VirtualAllocEx(processName.Handle, 0, dlllength, 4096, 4); 
if (baseaddress == 0) 
{ 
MessageBox.Show("申请内存空间失败!"); 
return; 
} 
//写内存 
int result = WriteProcessMemory(processName.Handle, baseaddress, dllName, dlllength, 0); 
if (result == 0) 
{ 
MessageBox.Show("写内存失败!"); 
return; 
} 
//取得loadlibarary在kernek32.dll地址 
int procAddress = GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA"); 
if (procAddress == 0) 
{ 
MessageBox.Show("无法取得函数的入口点!"); 
return; 
} 
//创建远程线程。 
result = CreateRemoteThread(processName.Handle, 0, 0, 0, baseaddress, 0, 0); 
if (result == 0) 
{ 
MessageBox.Show("创建远程线程失败!"); 
return; 
} 
else 
MessageBox.Show("已成功注入dll!"); 
} 
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在C# WebAPI中连接数据库,你需要采用以下步骤: 1. 首先,安装数据库提供程序(如SqlClient)。 2. 在WebAPI项目中添加连接字符串,该连接字符串应包含数据库服务器名称、数据库名称、用户名和密码。 3. 在WebAPI项目中创建一个类,该类将连接到数据库并执行查询或存储过程。 4. 在需要访问数据库的控制器中,创建一个类的实例,并调用该类中的方法以执行查询或存储过程。 下面是一个连接到SQL Server数据库的示例代码: ```csharp using System.Data.SqlClient; public class DataAccess { private readonly string _connectionString; public DataAccess(string connectionString) { _connectionString = connectionString; } public void ExecuteQuery(string query) { using (var connection = new SqlConnection(_connectionString)) { connection.Open(); using (var command = new SqlCommand(query, connection)) { command.ExecuteNonQuery(); } } } public SqlDataReader ExecuteReader(string query) { var connection = new SqlConnection(_connectionString); connection.Open(); var command = new SqlCommand(query, connection); return command.ExecuteReader(); } } ``` 在控制器中调用该类: ```csharp [ApiController] [Route("[controller]")] public class ProductsController : ControllerBase { private readonly string _connectionString; public ProductsController(IConfiguration configuration) { _connectionString = configuration.GetConnectionString("DefaultConnection"); } [HttpGet] public IEnumerable<Product> Get() { var dataAccess = new DataAccess(_connectionString); var reader = dataAccess.ExecuteReader("SELECT * FROM Products"); while (reader.Read()) { yield return new Product { Id = reader.GetInt32(0), Name = reader.GetString(1), Price = reader.GetDecimal(2) }; } } } ``` 在上面的代码中,我们在控制器中注入了一个 IConfiguration 对象,以获取连接字符串。然后,我们创建了一个 DataAccess 对象,并调用 ExecuteReader 方法来执行查询。最后,我们使用 SqlDataReader 对象来读取结果集。 ### 回答2: C是一种广泛使用的编程语言,由丹尼斯·里奇在1972年至1973年之间创建。它被设计成一种通用的编程语言,用于开发各种应用程序。C语言的设计目标是使程序员能够更好地控制计算机的硬件资源,同时具有高效性和可移植性。 C语言有很多特点和优势。首先,它是一种结构化的编程语言,使得程序的组织和维护更加容易。其次,C语言具有高效的执行速度和低内存消耗,这使得它在嵌入式系统和底层开发中得到广泛应用。此外,C语言还具有丰富的库函数和工具,使得程序开发更加便捷和高效。 与其他编程语言相比,C语言的学习曲线较为陡峭,需要掌握一些底层的概念和编程技巧。但一旦掌握了这些基础知识,就可以更好地理解和使用其他高级编程语言。因此,学习C语言对于计算机科学和软件工程领域的学生来说是非常重要的。 C语言在各个领域有广泛应用。它可以用于开发操作系统、网络协议、数据库管理系统等底层软件。同时,C语言也可以用于开发应用程序,如游戏、图形界面、金融软件等。许多著名的软件工具和系统也是使用C语言开发的。例如,UNIX操作系统、Linux内核、MySQL数据库等。 总的来说,C语言是一种重要的编程语言,具有广泛的应用范围和众多的优势。通过学习和掌握C语言,可以使我们更好地理解计算机的工作原理,培养编程思维和解决问题的能力,并为未来学习其他编程语言打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值