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路径

相关推荐
SuperHeroWu77 分钟前
【HarmonyOS】应用实现读取剪切板内容(安全控件和自读取)
安全·华为·harmonyos·鸿蒙·权限·剪切板·systepasteboard
raysync88810 分钟前
如何保障医院内部的隔离网安全跨网文件交换?
网络·安全
网络安全-杰克1 小时前
助力网络安全发展,安全态势攻防赛事可视化
网络·安全·web安全
Source.Liu1 小时前
不安全 Rust
安全·rust
Envyᥫᩣ1 小时前
深入浅出C#编程语言
开发语言·c#
IT小辉同学2 小时前
一键生成本地SSL证书:打造HTTPS安全环境
安全·https·ssl
weisian1513 小时前
认证鉴权框架SpringSecurity-2--重点组件和过滤器链篇
java·安全
Koi慢热3 小时前
信息收集合集
网络·安全·web安全·网络安全
机器人天才一号3 小时前
C#从入门到放弃
开发语言·c#
吾与谁归in3 小时前
【C#设计模式(10)——装饰器模式(Decorator Pattern)】
设计模式·c#·装饰器模式