返回顶部
首页 > 资讯 > 精选 >反射加载 CGO 生成的 DLL
  • 439
分享到

反射加载 CGO 生成的 DLL

2024-02-08 21:02:58 439人浏览 安东尼
摘要

问题内容 只是想尝试反射 dll 加载,所以我写了一个简单的消息框: package main import "c" import ( "unsafe" "syscal

问题内容

只是想尝试反射 dll 加载,所以我写了一个简单的消息框:

package main
import "c"
import (
    "unsafe"
    "syscall"
)

//export onprocessattach
func onprocessattach() {
    const (
        null  = 0
        mb_ok = 0
    )
    caption := "hola"
    title := "desdeGoo"
    ret, _, _ := syscall.newlazydll("user32.dll").newproc("messageboxw").call(
        uintptr(null),
        uintptr(unsafe.pointer(syscall.stringtoutf16ptr(caption))),
        uintptr(unsafe.pointer(syscall.stringtoutf16ptr(title))),
        uintptr(mb_ok))

    if ret != 1 {
        return
    }
    return
}

func main() {}

我使用以下命令生成了一个 dll(只是一个带有 cgo/golang 的消息框) go build --buildmode=c-shared main.go

当使用 loadlibrary() 加载 dll 并运行导出函数 onprocessattach 时,它可以工作(弹出消息框),但是当尝试实现 dll 反射加载时,通过解析重定位和解析 iat,它就不起作用。 似乎执行基本重定位并将 iat 设置为 .rdata 上的空部分,用于初始化 go 运行时(在 nt 标头的入口点中初始化) 这是我用来解决导入问题的代码片段:

// resolve base relocations
    IMAGE_DATA_DIRECTORY relocations = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
    DWord_PTR relocationTable = relocations.VirtualAddress + (DWORD_PTR)dllBase;
    DWORD relocationsProcessed = 0;


    while (relocationsProcessed < relocations.Size)
    {
        PBASE_RELOCATION_BLOCK relocationBlock = (PBASE_RELOCATION_BLOCK)(relocationTable + relocationsProcessed);
        relocationsProcessed += sizeof(BASE_RELOCATION_BLOCK);
        DWORD relocationsCount = (relocationBlock->BlockSize - sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY);
        PBASE_RELOCATION_ENTRY relocationEntries = (PBASE_RELOCATION_ENTRY)(relocationTable + relocationsProcessed);
        for (DWORD i = 0; i < relocationsCount; i++)
        {
            relocationsProcessed += sizeof(BASE_RELOCATION_ENTRY);
            if (relocationEntries[i].Type == 0)
            {
                continue;
            }


            DWORD_PTR relocationRVA = relocationBlock->PageAddress + relocationEntries[i].Offset;
            DWORD_PTR addressToPatch = 0;
            ReadProcessMemory(GetCurrentProcess(), (LPCVOID)((DWORD_PTR)dllBase, relocationRVA), &addressToPatch, sizeof(DWORD_PTR), NULL);
            addressToPatch += deltaImageBase;
            memcpy((PVOID)((DWORD_PTR)dllBase + relocationRVA), &addressToPatch, sizeof(DWORD_PTR));
        }
    }
    
    // resolve IAT
    PIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;
    IMAGE_DATA_DIRECTORY importsDirectory = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + (DWORD_PTR)dllBase);
    LPCSTR libraryName = "";
    HMODULE library = NULL;


    while (importDescriptor->Name != NULL)
    {
        libraryName = (LPCSTR)importDescriptor->Name + (DWORD_PTR)dllBase;
        library = LoadLibraryA(libraryName);
        if (library)
        {
            PIMAGE_THUNK_DATA thunk = NULL;
            thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)dllBase + importDescriptor->FirstThunk);
            while (thunk->u1.AddressOfData != NULL)
            {
                if (IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal))
                {
                    LPCSTR functionOrdinal = (LPCSTR)IMAGE_ORDINAL(thunk->u1.Ordinal);
                    thunk->u1.Function = (DWORD_PTR)GetProcAddress(library, functionOrdinal);
                }
                else {
                    PIMAGE_IMPORT_BY_NAME functionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)dllBase + thunk->u1.AddressOfData);
                    DWORD_PTR functionAddress = (DWORD_PTR)GetProcAddress(library, functionName->Name);
                    thunk->u1.Function = functionAddress;
                }
                ++thunk;
            }
        }
        importDescriptor++;
    }

这样做之后,我解决了 eat 寻找 onprocessattach 函数的问题,直接运行它显然不起作用,因为 go 运行时未初始化,但尝试初始化它会导致程序崩溃,因为如上所述。它会给出 exception_access_violation,因为尝试读取无效的字节块。

入口点的反汇编: mov rax, qdword ptr ds:[地址] mov dword ptr ds:[rax]

按照转储中的地址,它看起来为空 00 00 00 00 00 00 00 00 00 [..]

虽然原始dll确实有值 90 2b c5 ea 01 [...]

我知道我将 .rdata 上的这些字节设置为 null,但无法弄清楚为什么在执行重定位时会发生这种情况,也许 go 运行时不适合我想要做的事情?还是别的什么?


正确答案


解决后我只是忘了在这里发布解决方案 错误出现在以下行

ReadProceSSMemory(GetCurrentProcess(), (LPCVOID)((DWORD_PTR)dllBase, relocationRVA), &addressToPatch, sizeof(DWORD_PTR), NULL);

这只是一个手指错误,应该是添加符号而不是逗号,这就是它使地址无效的原因。

以上就是反射加载 CGO 生成的 DLL的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: 反射加载 CGO 生成的 DLL

本文链接: https://lsjlt.com/news/562046.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 反射加载 CGO 生成的 DLL
    问题内容 只是想尝试反射 dll 加载,所以我写了一个简单的消息框: package main import "c" import ( "unsafe" "syscal...
    99+
    2024-02-08
  • java Stream流常见操作方法(反射,类加载器,类加载,反射)
    目录Stream流常见的中间操作方法Stream流中常见的终结操作方法反射类加载器反射概述Stream流常见的中间操作方法 Streamfilter(Predicate predic...
    99+
    2024-04-02
  • Cgo 生成的源无法在 MVC 上编译
    来到编程网的大家,相信都是编程学习爱好者,希望在这里学习Golang相关编程知识。下面本篇文章就来带大家聊聊《Cgo 生成的源无法在 MVC 上编译》,介绍一下,希望对大家的知识积累有所帮助,助力实...
    99+
    2024-04-05
  • 怎么在java中利用反射生成对象
    这期内容当中小编将会给大家带来有关怎么在java中利用反射生成对象,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系...
    99+
    2023-06-14
  • Java反射的深入探索:掌握类加载的奥秘
    Reflection,也被称为Java反射,允许您在运行时检查和修改类的属性、方法和构造函数。虽然在Java开发中理解Reflection非常重要,但它也很复杂。在本文中,我们将深入探讨Reflection,帮助您理解它的工作原理并掌握其...
    99+
    2024-02-09
    Java反射 类加载 动态代理 Java虚拟机
  • golang 反射在元编程和代码生成中的应用
    反射在 go 语言中的元编程和代码生成中十分有用:元编程:允许程序在运行时创建新类型、函数和变量,修改现有类型结构。代码生成:可以动态生成代码片段,并在运行时执行它们,例如生成实现特定接...
    99+
    2024-05-04
    反射 元编程 代码生成 golang
  • Java程序集加载和反射机制是什么
    本篇内容介绍了“Java程序集加载和反射机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、程序集的加载JIT编译器器将IL代码编译...
    99+
    2023-06-17
  • 如何利用反射生成 MyBatisPlus中QueryWrapper动态条件
    目录1.问题2.优化方案1.问题 在MyBatisPlus中经常会用到如下所示的代码来构造查询条件: QueryWrapper<User> queryWrapper = ...
    99+
    2024-04-02
  • 怎么利用反射生成MyBatisPlus中QueryWrapper动态条件
    这篇文章主要介绍了怎么利用反射生成MyBatisPlus中QueryWrapper动态条件的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么利用反射生成MyBatisPlus中QueryWrapper动态条件文...
    99+
    2023-06-29
  • 如何使用 cgo 在 golang 中导入 cython 生成的文件
    今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《如何使用 cgo 在 golang 中导入 cython 生成的文件》,主要内容是讲解等等,感兴趣的朋友可以收藏或...
    99+
    2024-04-05
  • C#中如何使用反射和动态加载程序集
    C#中如何使用反射和动态加载程序集引言:在C#中,反射(Reflection)是一种强大的机制,它允许我们在运行时获取和操作程序的元数据,包括类型信息、成员信息等。而动态加载程序集则是通过反射来实现的一种常见应用,并且在一些特定场景中非常有...
    99+
    2023-10-22
    C# 反射 动态加载
  • JDBC以反射机制加载类注册驱动连接MySQL
    package test.jdbc; //JDBC注册驱动的另一种方式:(这种方式常用) public class JDBC3 { public static void m...
    99+
    2024-04-02
  • C# WPF如何反射加载Geometry几何图形数据图标
    目录为什么要用Geometry数据做图标?怎么获取Geometry数据?如何使用Geometry数据相信大家在阅读WPF相关GitHub开源项目源码时都会看见一串串这种数据 这种G...
    99+
    2024-04-02
  • linux生成(加载)动态库静态库和加载示例方法
    动态库的生成: 1、 #include <stdio.h>#include "src.h" int sum(int a,int b){return (a+b);} 2、 #ifndef ...
    99+
    2022-06-04
    加载 示例 静态
  • C#生成带注释的dll并引用实现
    目录一. 编写.cs文件二. 生成XML文件注释三. 打开MSBuild Command Prompt for VS2015生成dll文件四. 使用另一个项目引用...
    99+
    2024-04-02
  • C#怎么生成带注释的dll并引用
    本篇内容主要讲解“C#怎么生成带注释的dll并引用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#怎么生成带注释的dll并引用”吧!一. 编写.cs文件注:要想编译dll中注释可用,则代码中的...
    99+
    2023-06-29
  • C#中通过反射将枚举元素加载到ComboBo的实现方法
    目录一、前言二、思路三、上代码一、前言        做过系统参数设置的同学们,肯定遇到过要提供一系列具有相同特点的选项供用户选择。最初级的做...
    99+
    2024-04-02
  • C#加载嵌入到资源的非托管dll
    如何加载非托管Dll 我们总会遇到需要加载非Win32的非托管dll,这里推荐一种方式就是将那些非win32的非托管dll嵌入资源的方式,在入口解压并且加载的方式,我先来看看如何实现...
    99+
    2024-04-02
  • 加载 dll 失败。找不到指定的模块
    大家好,今天本人给大家带来文章《加载 dll 失败。找不到指定的模块》,文中内容主要涉及到,如果你对Golang方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢!问题内容我有...
    99+
    2024-04-04
  • Java如何加载数组并生成二维码?
    二维码是一种常用的二维条码,它可以存储大量的信息,包括文本、URL、电话号码等等。在Java中,我们可以使用一些开源库来生成二维码,如zxing和qrcode等。本文将介绍如何使用Java加载数组并生成二维码。 一、使用zxing生成二维...
    99+
    2023-08-09
    load 数组 二维码
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作