c#的反汇编对抗

文章目录

前记

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

c# 复制代码
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

nim 复制代码
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

nim 复制代码
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()

内存加载

读取字节流

nim 复制代码
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

nim 复制代码
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

nim 复制代码
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}"
nim 复制代码
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#类型转换表

Windows C#
BOOL int
BOOLEAN byte
BYTE byte
UCHAR byte
UINT8 byte
CCHAR byte
CHAR sbyte
CHAR sbyte
INT8 sbyte
CSHORT short
INT16 short
SHORT short
ATOM ushort
UINT16 ushort
USHORT ushort
WORD ushort
INT int
INT32 int
LONG int
LONG32 int
CLONG uint
DWORD uint
DWORD32 uint
UINT uint
UINT32 uint
ULONG uint
ULONG32 uint
INT64 long
LARGE_INTEGER long
LONG64 long
LONGLONG long
QWORD long
DWORD64 ulong
UINT64 ulong
ULONG64 ulong
ULONGLONG ulong
ULARGE_INTEGER ulong
HRESULT int
NTSTATUS int

nim基础

语法速记

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

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全覆盖

nim 复制代码
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

三、迭代器

nim 复制代码
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

四、块语句

nim 复制代码
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"

五、缩进原则

nim 复制代码
# 单个赋值语句不需要缩进:
if x: x = false

# 嵌套if语句需要缩进:
if x:
  if y:
    y = false
  else:
    y = true

# 需要缩进, 因为条件后有两个语句:
if x:
  x = false
  y = false

六、函数

nim 复制代码
proc yes(question: string): bool =
  echo question, " (y/n)"
  while true:
    case readLine(stdin)
    of "y", "Y", "yes", "Yes": return true
    of "n", "N", "no", "No": return false
    else: 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+b

echo add(1,89)

proc sumTillNegative(x: varargs[int]): int =
  for i in x:
    if i < 0:
      return
    result = result + i

echo sumTillNegative() # echos 0
echo sumTillNegative(3, 4, 5) # echos 12

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

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

七、传实参

nim 复制代码
proc divmod(a, b: int; res: var int,remainder:var int) =
  res = a div b        # 整除
  remainder = a mod b  # 整数取模操作

var x, y=111

divmod(8, 5, x, y) # 修改x和y
echo x
echo y

传递实参用var修饰

八、忽略返回值discard

nim 复制代码
proc p(x, y: int): int {.discardable.} =
  return x + y

var c:int
c=p(3, 4) # now valid
echo c
p(3, 4)

九、数组初始化

nim 复制代码
type
  IntArray = array[0..7, int] # 一个索引为0..7的数组
  QuickArray = array[6, int]  # 一个索引为0..5的数组
var
  x: 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 i
  
for i, v in @[3, 7, 5]:
  echo "index: ", $i, ", value:", $v
# --> index: 0, value:3
# --> index: 1, value:4
# --> index: 2, value:5

十、结构体

nim 复制代码
type
  Person = object
    name: string
    age: int

var person1 = Person(name: "Peter", age: 30)

echo person1.name # "Peter"
echo person1.age  # 30

var person2 = person1 # 复制person 1

十一、读写文件

nim 复制代码
#字节流
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路径

相关推荐
fujisheng66113 分钟前
Unity 异步 UI 实战:取消令牌、版本校验与旧句柄隔离
c#·unity3d
秋名RG17 分钟前
Java 泛型深度解析:从类型安全到现代实践(JDK 21 视角)
java·windows·安全
额鹅恶饿呃1 小时前
随着CentOS官方停服的时间越来越久,大量仍在使用CentOS7的企业和运维从业者
java·python·算法·c#·ruby
乌药ice1 小时前
c#中一个多线程安全的HashSet
开发语言·c#
AI 思录1 小时前
Prompt 事故档案(五):AI 道歉,还是“道德漂白”?
人工智能·安全·prompt·用户体验·ai安全·ai幻觉
学逆向的1 小时前
PE——RVA与FOA的转换
开发语言·网络安全·pe
2601_962097562 小时前
摩根大通:AI发现漏洞速度远超修补能力 网络风险持续累积
网络安全·ai·工业设施·漏洞修补·补丁缺口
是隼人2 小时前
buuctf-pwn wustctf2020_closed(文件描述符)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
lfSeanDragon2 小时前
数据结构-前缀树(Trie)
开发语言·c#
YOLO数据集集合2 小时前
工地开放危险区域检测数据集 | 工地安全 开放区域检测 临边防护9050期
安全·无人机·工地·工地安全·工地检测·危险区域监测