主页 > IT业界  > 

c#的反汇编对抗

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#BOOLintBOOLEANbyteBYTEbyteUCHARbyteUINT8byteCCHARbyteCHARsbyteCHARsbyteINT8sbyteCSHORTshortINT16shortSHORTshortATOMushortUINT16ushortUSHORTushortWORDushortINTintINT32intLONGintLONG32intCLONGuintDWORDuintDWORD32uintUINTuintUINT32uintULONGuintULONG32uintINT64longLARGE_INTEGERlongLONG64longLONGLONGlongQWORDlongDWORD64ulongUINT64ulongULONG64ulongULONGLONGulongULARGE_INTEGERulongHRESULTintNTSTATUSint 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 = false else: y = true # 需要缩进, 因为条件后有两个语句: if x: x = false y = false

六、函数

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语句

七、传实参

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

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

九、数组初始化

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

十、结构体

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

十一、读写文件

#字节流 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#的反汇编对抗由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“c#的反汇编对抗