当前位置:首页 » 《随便一记》 » 正文

c#的反汇编对抗

3 人参与  2024年03月05日 11:46  分类 : 《随便一记》  评论

点击全文阅读


文章目录

前记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 osvar buf: array[4096,byte]var f: Filef = open(r"D:\c_project\nim\test.exe")discard readBytes(f, buf,0,4096)f.close()echo buf

c.exe>aaa.txt

import winim/clrimport sugarimport osvar 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 base64import osimport strformatfunc 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 sequencevar bytesequence: seq[byte] = toByteSeq(inFileContents)let encoded = encode(bytesequence)echo fmt"[*] Encoded: {encoded}"
import base64import osimport strformatimport winim/clrimport sugarimport osfunc 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 nameof "":  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 parseIntecho "A number please: "let n = parseInt(readLine(stdin))case nof 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 ifor i in countdown(6, 2):  echo ifor i in 10..19:    echo ifor 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+becho add(1,89)proc sumTillNegative(x: varargs[int]): int =  for i in x:    if i < 0:      return    result = result + iecho sumTillNegative() # echos 0echo 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和yecho xecho y

传递实参用var修饰

八、忽略返回值discard

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

九、数组初始化

type  IntArray = array[0..7, int] # 一个索引为0..7的数组  QuickArray = array[6, int]  # 一个索引为0..5的数组var  x: IntArrayx = [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: intvar person1 = Person(name: "Peter", age: 30)echo person1.name # "Peter"echo person1.age  # 30var person2 = person1 # 复制person 1

十一、读写文件

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

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


点击全文阅读


本文链接:http://zhangshiyu.com/post/74018.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1