文章目录

前记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

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

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: