c#的反汇编对抗

2024-02-03 01:20
文章标签 c# .net 对抗 netcore 反汇编

本文主要是介绍c#的反汇编对抗,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 前记
    • nim攻防基础
      • FFI
      • 内存加载
      • 加解密、编码
    • 后记
      • C#类型转换表
      • nim基础

前记

随便编写一个c#调用winapi并用vs生成dll,同时用csc生成exe

using System;
using System.Runtime.InteropServices;
namespace coleak
{class winfun{[DllImport("User32.dll")]public static extern int MessageBox(IntPtr h, string m, string c, uint type);[DllImport("kernel32.dll", EntryPoint = "Beep")]public static extern bool mymethod(uint frequency, uint duration);}class Program{static void Main(string[] args){winfun winfun = new winfun();winfun.MessageBox((IntPtr)0, "yueyy", "coleak",(uint) 0);Random random = new Random();for (int i = 0; i < 10000; i++){winfun.mymethod((uint)random.Next(10000), 100);}Console.ReadLine();}}
}
/*BOOL Beep(
DWORD dwFreq,
DWORD dwDuration
);
int MessageBox([in, optional] HWND hWnd,[in, optional] LPCTSTR lpText,[in, optional] LPCTSTR lpCaption,[in] UINT uType
);*/

优点:隐藏导入表,仅存在mscoree.dll

缺点:在dnspy下均直接出源码

nim攻防基础

为了更加OPSEC,考虑使用nim代替c#核心部分,nim防止反编译同时也不暴露导入函数

FFI

proc MessageBoxA*(hWnd: int, lpText: cstring, lpCaption: cstring, uType: int32): int32 {.discardable, dynlib: "user32", importc.}
MessageBoxA(0, "Hello, world !", "MessageBox Example", 0)proc WinExec*(lpCmdLine:cstring,uCmdShow:int32): int32 {.discardable,dynlib:"kernel32",importc.}
WinExec("calc.exe",0)proc printf(format: cstring): cint {.importc, varargs,discardable.}#discardable忽略返回值否则报错
printf("My name is %s and I am %d years old!\n", "coleak", 20)proc mycmp(a, b: cstring): cint {.importc: "strcmp", nodecl.} #=proc strcmp(a, b: cstring): cint {.importc, nodecl.}
let cmp = strcmp("Easy!", "Easy!")
echo cmp

嵌入c

when not defined(c):{.error: "Must be compiled in c mode"}
{.emit: """
#include <stdio.h>
int Test() {char name[100]={0};scanf("%s",name);printf("嵌入成功,%s",name);return 0;} // end main 
""".}proc Test(): int{.importc: "Test", nodecl,discardable.}
when isMainModule:discard Test()

内存加载

读取字节流

import os
var buf: array[4096,byte]
var f: File
f = open(r"D:\c_project\nim\test.exe")
discard readBytes(f, buf,0,4096)
f.close()
echo buf

c.exe>aaa.txt

import winim/clr
import sugar
import os
var buf: array[4096,byte]
buf = [77, 90, ..., 0]
var assembly = load(buf)
var arr = toCLRVariant(commandLineParams(), VT_BSTR)
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

c#虽然没有暴露导入信息,但是在hxd下会暴露字符串信息,因此在 Nim 编译的可执行文件中检测 .NET 程序集仍然很容易,还可以用hxd轻松搜到nim加载的程序集中存在的user32.dll字符信息和exe关键词

在这里插入图片描述

加解密、编码

base64

import base64
import os
import strformat
func toByteSeq*(str: string): seq[byte] {.inline.} =# Converts a string to the corresponding byte sequence@(str.toOpenArrayByte(0, str.high))
let inFile: string = paramStr(1)
let inFileContents: string = readFile(inFile)
# To load this .NET assembly we need a byte array or sequence
var bytesequence: seq[byte] = toByteSeq(inFileContents)
let encoded = encode(bytesequence)
echo fmt"[*] Encoded: {encoded}"
import base64
import os
import strformat
import winim/clr
import sugar
import os
func toByteSeq*(str: string): seq[byte] {.inline.} =# Converts a string to the corresponding byte sequence@(str.toOpenArrayByte(0, str.high))
let encoded = r"TVqQAAMAAAAEAAAA//8...AAA=="
let decoded = decode(encoded)
let mys=toByteSeq(decoded)
var assembly = load(mys)
var arr = toCLRVariant(commandLineParams(), VT_BSTR)
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

可以换成别的方式加密.NET 程序集,用于运行时解密

后记

C#类型转换表

WindowsC#
BOOLint
BOOLEANbyte
BYTEbyte
UCHARbyte
UINT8byte
CCHARbyte
CHARsbyte
CHARsbyte
INT8sbyte
CSHORTshort
INT16short
SHORTshort
ATOMushort
UINT16ushort
USHORTushort
WORDushort
INTint
INT32int
LONGint
LONG32int
CLONGuint
DWORDuint
DWORD32uint
UINTuint
UINT32uint
ULONGuint
ULONG32uint
INT64long
LARGE_INTEGERlong
LONG64long
LONGLONGlong
QWORDlong
DWORD64ulong
UINT64ulong
ULONG64ulong
ULONGLONGulong
ULARGE_INTEGERulong
HRESULTint
NTSTATUSint

nim基础

语法速记

一、分支允许使用逗号分隔的值列表

let name = readLine(stdin)
case name
of "":echo "Poor soul, you lost your name?"
of "name":echo "Very funny, your name is name."
of "Dave", "Frank":echo "Cool name!"
else:echo "Hi, ", name, "!"

二、of全覆盖

from strutils import parseInt
echo "A number please: "
let n = parseInt(readLine(stdin))
case n
of 0..2, 4..7: echo "The number is in the set: {0, 1, 2, 4, 5, 6, 7}"
of 3, 8: echo "The number is 3 or 8"
else: discard

三、迭代器

echo "Counting down from 10 to 1: "
for i in countup(1, 5):echo i
for i in countdown(6, 2):echo i
for i in 10..19:echo i
for i in 1..<19:echo i

四、块语句

block myblock:echo "entering block"while true:echo "looping"break # 跳出循环,但不跳出块echo "still in block"block myblock2:echo "entering block"while true:echo "looping"break myblock2 # 跳出块 (和循环)echo "still in block"

五、缩进原则

# 单个赋值语句不需要缩进:
if x: x = false# 嵌套if语句需要缩进:
if x:if y:y = falseelse:y = true# 需要缩进, 因为条件后有两个语句:
if x:x = falsey = false

六、函数

proc yes(question: string): bool =echo question, " (y/n)"while true:case readLine(stdin)of "y", "Y", "yes", "Yes": return trueof "n", "N", "no", "No": return falseelse: echo "Please be clear: yes or no"if yes("Should I delete all your important files?"):echo "I'm sorry , I'm afraid I can't do that."
else:echo "I think you know what the problem is just as well as I do."proc add(a:int,b:int):int=return a+becho add(1,89)proc sumTillNegative(x: varargs[int]): int =for i in x:if i < 0:returnresult = result + iecho sumTillNegative() # echos 0
echo sumTillNegative(3, 4, 5) # echos 12

函数定义格式看起来很繁琐,返回值类型放在: bool =

result 总在过程的结尾自动返回如果退出时没有 return语句

七、传实参

proc divmod(a, b: int; res: var int,remainder:var int) =res = a div b        # 整除remainder = a mod b  # 整数取模操作var x, y=111divmod(8, 5, x, y) # 修改x和y
echo x
echo y

传递实参用var修饰

八、忽略返回值discard

proc p(x, y: int): int {.discardable.} =return x + yvar c:int
c=p(3, 4) # now valid
echo c
p(3, 4)

九、数组初始化

typeIntArray = array[0..7, int] # 一个索引为0..7的数组QuickArray = array[6, int]  # 一个索引为0..5的数组
varx: IntArray
x = [1, 5, 3, 4, 5, 77,9,8]
for i in low(x)..high(x):echo x[i]
for i in x:echo ifor i, v in @[3, 7, 5]:echo "index: ", $i, ", value:", $v
# --> index: 0, value:3
# --> index: 1, value:4
# --> index: 2, value:5

十、结构体

typePerson = objectname: stringage: intvar person1 = Person(name: "Peter", age: 30)echo person1.name # "Peter"
echo person1.age  # 30var person2 = person1 # 复制person 1

十一、读写文件

#字节流
import os
var buf: array[100,byte]
var f: File
f = open("D:\\c_project\\nim\\d.exe")
discard readBytes(f, buf,0,9)
f.close()
echo buf#文本文件
var file:File
file = open(r"D:\c_project\nim\d.txt")
echo file.readAll()
file.close()let text = "Cats are very cool!"
writeFile("cats.txt", text)

十二、绝对路径默认目录为shell路径

这篇关于c#的反汇编对抗的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/672585

相关文章

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

C#基础之委托详解(Delegate)

《C#基础之委托详解(Delegate)》:本文主要介绍C#基础之委托(Delegate),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 委托定义2. 委托实例化3. 多播委托(Multicast Delegates)4. 委托的用途事件处理回调函数LINQ

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

C#中的 StreamReader/StreamWriter 使用示例详解

《C#中的StreamReader/StreamWriter使用示例详解》在C#开发中,StreamReader和StreamWriter是处理文本文件的核心类,属于System.IO命名空间,本... 目录前言一、什么是 StreamReader 和 StreamWriter?1. 定义2. 特点3. 用

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.