C#黑客编程必须掌握的知识 (下)

admin 2024年12月22日01:54:43评论11 views字数 3488阅读11分37秒阅读模式

C#黑客编程必须掌握的知识 (下)

结构体封送

win32API中有很多需要结构体的场景,当你使用C#进行平台调用的时候,也需要遵循相应的规则,如果在windows平台存在一个如下的结构体:

typedefstruct_mstruct{    DWORD Reserve1;int Reserve2;wchar_t str[128];    WORD Reserve3;    byte Reserve4;}mstruct,*pmstruct;

则在c#代码中需要做如下定义:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]publicstruct mstruct {public UInt32 Reserve1;publicint Reserve2;    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]publicstring str;public UInt16 Reserve3;publicbyte Reserve4;}

首先是结构体StructLayout属性,这个属性可以指定结构体在内存的布局:

  • • LayoutKind.Sequential - 根据结构体定义字段的顺序在内存进行布局。
  • • LayoutKind.Explicit - 需要在每个字段上设定[FieldOffset()],来确定在在结构体中的偏移位置。
  • • LayoutKind.Auto - 由.net运行时自动确定所需的布局方式 在c风格中结构体中的字符数组wchar_t str[128]在c#中定义时,需要设定传入字符串SizeConst大小属性,通过nmanagedType.ByValTStr设定封送类型,同时在StructLayout中指定编码格式。

此外 StructLayout特性支持三种附加字段:CharSet、Pack、Size:

  • • CharSet定义在结构中的字符串成员在结构被传给DLL时的排列方式。可以是Unicode、Ansi或Auto。
  • • Pack 定义结构体字段在内存中的对齐方式。
  • • Size 指示结构的绝对大小,该字段必须等于或大于类或结构成员的总大小(以字节为单位)。

C#中的指针

C#不支持指针,我们可以使用unsafe关键词,开启不安全代码(unsafe code)开发模式,从而可以访问内存,达到指针的效果。

staticint[] Modify(){int[] array=newint[10];for (int i = 0; i < array.Length; i++)     {        array[i] = i;    }return array;}staticvoidMain(){var array = Modify();unsafe    {fixed (int* ptr = array)        {for (int i = 0; i < array.Length; i++)            {                Console.WriteLine(*(ptr+i));            }        }    }    Console.ReadLine();}

我们首先构造一个托管类型的整数数组,假设我们需要通过访问内存来访问元素内容。首先所以的涉及到指针的代码都必须放在unsafe代码块中,然后我们需要用fixed关键字来获取指向托管对象的指针,并且保证该指针不会被移动。接下来就跟c语言一样,正常访问内存数据就行。

PtrToStructure与StructureToPtr

这两个函数,从字面意思上来看,分别是获取结构指针以及将一块内存封装为结构体,官方的说法是:将数据从非托管内存块编组到托管对象(前者),将数据从托管对象编组到非托管内存块(后者)。

API原型:

publicstaticobject? PtrToStructure (IntPtr ptr, Type structureType);ptr - 指向非托管内存块的指针structureType - 要创建的对象的类型publicstaticvoidStructureToPtr (object structure, IntPtr ptr, bool fDeleteOld);structure - 保存要转换的托管对象ptr  - 指向非托管内存块的指针fDeleteOld - true表示在此方法复制数据之前对ptr参数调用DestroyStructure(IntPtr, Type)方法

官方案例:

publicstruct Point{publicint x;publicint y;}staticvoidMain(){// Create a point struct.    Point p;    p.x = 1;    p.y = 1;    Console.WriteLine("The value of first point is " + p.x + " and " + p.y + ".");// Initialize unmanged memory to hold the struct.    IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(p));try    {// Copy the struct to unmanaged memory.        Marshal.StructureToPtr(p, pnt, false);// Create another point.        Point anotherP;// Set this Point to the value of the// Point in unmanaged memory.        anotherP = (Point)Marshal.PtrToStructure(pnt, typeof(Point));        Console.WriteLine("The value of new point is " + anotherP.x + " and " + anotherP.y + ".");    }finally    {// Free the unmanaged memory.        Marshal.FreeHGlobal(pnt);    }}

利用委托来动态调用Win32 api

在win32中我们一般动态调用某个API一般会定义函数指针,然后利用GetProcAddress得到API地址,然后利用函数指针来执行。c#中并没有函数指针的定义,但是可以通过委托来实现同样的效果:

[DllImport("Kernel32", CharSet = CharSet.Ansi, EntryPoint = "LoadLibraryA", SetLastError = true)]publicstaticextern IntPtr LoadLibraryA(String funcname);[DllImport("Kernel32")]publicstaticextern IntPtr GetProcAddress(IntPtr handle, String funcname);[UnmanagedFunctionPointer(CallingConvention.StdCall,CharSet=chars)]privatedelegateintDMessageBoxW(IntPtr hwnd, string text, string cap, uint type);staticvoidMain(){    DMessageBoxW dMessageBoxW = (DMessageBoxW)Marshal.GetDelegateForFunctionPointer(GetProcAddress(LoadLibraryA("user32.dll"), "MessageBoxW"), typeof(DMessageBoxW));    dMessageBoxW(IntPtr.Zero, "你好""世界"0);}

定义委托时,参数类型以及个数需要保持一致,同时需要指定调用约定,然后可以利用GetDelegateForFunctionPointer来为我们的函数地址转换为我们的委托,然后调用即可。

这是一个纯粹,开放,前沿的技术交流社区,成员主要有互联网大厂安全部门任职的成员,乙方红队专家,以及正在学习入门的小白等,社区涉及的领域知识包括但不限于渗透,免杀开发,红蓝对抗,安全建设,考试认证,岗位招聘等等方面,还可以结识很多志同道合的朋友,提升自己的技术栈,开阔视野,提升眼界👇👇👇

C#黑客编程必须掌握的知识 (下)
C#黑客编程必须掌握的知识 (下)

欢迎加入交流圈

扫码获取更多精彩

C#黑客编程必须掌握的知识 (下)
C#黑客编程必须掌握的知识 (下)
C#黑客编程必须掌握的知识 (下)

原文始发于微信公众号(黑晶):C#黑客编程必须掌握的知识 (下)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月22日01:54:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   C#黑客编程必须掌握的知识 (下)https://cn-sec.com/archives/3537906.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息