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

admin 2024年12月20日10:46:05评论11 views字数 3368阅读11分13秒阅读模式

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

Win32API平台调用

托管代码调用win32API必须的三个步骤:

  • 获得非托管函数的信息,即dll的名称,需要调用的非托管函数名等信息

  • 在托管代码中对非托管函数进行声明,并且附加平台调用所需要属性

  • 在托管代码中直接调用第二步中声明的托管函数 代码调用MessageBoxW API:

  1. [DllImport("user32.dll",CharSet=CharSet.Unicode,EntryPoint="MessageBoxW",SetLastError=true)]

  2. publicstaticexternintMessageBoxW(IntPtr hWnd,String text,String caption,uint type);

  3. staticvoidMain(string[] args)

  4. {

  5. MessageBoxW(IntPtr.Zero,"你好","你好",0);

  6. }

非托管函数API声明必须具有static extern 关键字,返回值根据目标API返回值设定即可。

  1. [DllImport("user32.dll",CharSet=CharSet.Unicode,EntryPoint="MessageBoxW")]

上述代码定义了平台调用所需的属性,DllImport指定了API所在的模块,CharSet设定了字符集,如果你使用的字符串包含中文等字符,这里记得设定为Unicode,EntryPoint指定函数的实际入口,意思就是说你这里指定了某个入口函数后,你的函数声明的时候用任意函数名也可。比如:

  1. [DllImport("user32.dll",CharSet=CharSet.Unicode,EntryPoint="MessageBoxW",SetLastError=true)]

  2. publicstaticexternintMessageBoxssssW(IntPtr hWnd,String text,String caption,uint type);

  3. staticvoidMain(string[] args)

  4. {

  5. MessageBoxssssW(IntPtr.Zero,"你好","你好",0);

  6. }

获取Win32 ERROR信息

获取win32非托管代码的error信息,需要在平台调用API声明的属性中添加SetLastError=true,即:

  1. [DllImport("kernel32.dll",CharSet=CharSet.Unicode,EntryPoint="GetFileAttributes",SetLastError=true)]

  2. publicstaticexternintGetFileAttributes(String filename);

  3. staticvoidMain(string[] args)

  4. {

  5. GetFileAttributes("notfound.exe");

  6. int code =Marshal.GetLastWin32Error();

  7. Win32Exception win32exception =newWin32Exception(code);

  8. if(code !=0)

  9. {

  10. Console.WriteLine("调用Win32函数发生错误,错误信息为 : {0}", win32exception.Message);

  11. }

  12. else

  13. {

  14. Console.WriteLine("调用Win32函数成功,返回的信息为:{0}", win32exception.Message);

  15. }

  16. }

直接复制到本机结构中的类型和非直接复制到本机结构中的类型

  • 大多数数据类型在托管和非托管内存中具有共同的表示形式,而且不需要互操作封送处理程序进行特殊处理。这些类型称为 blittable 类型,因为它们在托管和非托管代码之间传递时不需要进行转换。

    windows数据类型 C数据类型 托管数据类型
    Uchar unsigned char System.Byte
    Char char System.SByte
    Short/Int16 short System.Int16
    USHORT/WORD unsigned short System.UInt16
    Int int System.Int32
    UINT/DWORD unsigned int System.UInt32
    INT64/LONGLONG _int64 System.Int64
    UINT64/ULONGLONG _uint64 System.UInt64
    INT_PTR void* System.IntPtr
    HANDLE void* System.UIntPtr
    FLOAT float System.Single
    DOUBLE _double System.Double
  • 在非托管环境中,某些托管数据类型要求具有不同的表示形式。必须将这些非 blittable 数据类型转换为可以封送的形式。例如,托管字符串就是非 blittable 类型,因为这些字符串必须转换为字符串对象后才能进行封送。

  1. 类型描述

  2. System.Array转换为 C 样式数组或 SAFEARRAY

  3. System.Boolean转换为124字节的值,true表示1-1

  4. System.Char转换为Unicode ANSI 字符。

  5. System.Class转换为类接口。

  6. System.Object转换为变量或接口。

  7. System.String转换为空引用中的终止字符串或转换为 BSTR。非托管代码不能更新此字符串。

  8. System.StringBuilder ANSI字符串/Unicode字符串,非托管代码可以更新此字符串,并传回给托管代码。

  9. System.ValueType转换为具有固定内存布局的结构。

字符串的封送处理

我们以GetModuleFileNameA API举例,这个API接收一个字符串地址用于写入模块名称字符串,返回值为实际写入lpFilename缓冲区的长度

  1. DWORD GetModuleFileNameA(

  2. [in, optional] HMODULE hModule,

  3. [out] LPSTR lpFilename,

  4. [in] DWORD nSize

  5. );

c++中我们调用的话代码一般这么写:

  1. char buffer[256];

  2. DWORD NameSTR=GetModuleFileNameA(NULL,buffer,256);

C#中调用首先定义函数声明:

  1. [DllImport("kernel32.dll",CharSet=CharSet.Unicode,EntryPoint="GetModuleFileNameW",SetLastError=true)]

  2. staticexternintGetModuleFileNameW(IntPtr hModule,StringBuilder lpFilename,int nSize);

注意上述Windows参数类型为LPSTR,我们在托管代码中需要使用StringBuilder类型,代码如下:

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

ref和out关键字

ref 和 out关键字会在涉及到结果传出的过程时用到。

out关键字:

用于从方法中返回参数值,方法的内部必须为out参数赋值,适用于返回多个值的场景,传递参数是out关键字需要一起传递:

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

ref 关键字:

ref 关键字用于将参数以引用方式传递给方法。这意味着方法中对该参数的修改会影响到调用方法时的原始变量。使用 ref 时,调用方和方法方都能看到相同的内存位置,因此任何对参数的修改都会反映到调用方的变量上。

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

主要区别

  • 初始化要求:
    ref:传递前,调用方的变量必须已初始化。
    out:传递前,调用方的变量可以不初始化。

  • 方法内部赋值:
    ref:方法可以选择修改或不修改传入的值,但如果修改了,调用方的值会反映出来。
    out:方法必须对参数进行赋值。

  • 使用场景:
    ref 用于方法需要访问和修改传入参数的场景。
    out 用于方法需要返回多个值的场景。

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

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

欢迎加入交流圈

扫码获取更多精彩

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

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

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

发表评论

匿名网友 填写信息