2025年go语言逆向学习笔记(三)c、go混合编程

go语言逆向学习笔记(三)c、go混合编程本人小白 记录一下 golang 的学习过程 首先 让我们看看 cgo 库是如何运行的 抱怨一句 昨天不知道怎么了 我 go 语言环境崩了 搞了我一天 麻了 package main include stdio h include stdio h

大家好,我是讯享网,很高兴认识大家。

本人小白,记录一下golang的学习过程,首先,让我们看看cgo库是如何运行的,抱怨一句:昨天不知道怎么了,我go语言环境崩了,搞了我一天,麻了。

package main /* #include <stdio.h> #include <stdlib.h> static void Hello(const char* s) { puts(s); } void check(){ printf("this is in c code\n"); } */ import "C" import "unsafe" func main() { C.check() msg := C.CString("Hello, World\n") defer C.free(unsafe.Pointer(msg)) //释放内存 C.Hello(msg) } 

讯享网

最开始我们执行了一个check函数,放入ida之后发现,ida能够识别check函数,而且ida的字符串窗口确实有this is in c code 的字符串,但是交叉引用找不到引用的函数,而check函数一定被使用了,所以猜想是call+寄存器之类的指令。


讯享网

然后开始调试,从这个地方开始将check函数的地址放入rax中,在断点的cgocall里执行了check函数,

 这里就验证了之前的猜想,确实是call rax,但是,对这个check函数,我发现了一个新的问题,希望有大佬教教。

 左图是golang编译的check函数,右图是c编译的check函数,为了保障严谨,两个都是同一个版本的gcc,同一个版本的ida,而且我golang源码中也用的是printf,为什么变成了puts

 那么,有意思的就来了,整个函数开始危险了,稍微改改check,内存泄露了,如下图,

 回到golang中的hello函数,对于函数的执行,与check大同小异,只是defer的free值得跟进

 该位置原本是储存hello,world字符串的,free过后是真的free了。

第二步,对于golang中C函数的嵌套

讯享网package main /* #include <stdio.h> #include <stdlib.h> int dfs(int a ){ printf("%d",a); return 6666; } int check(){ printf("this is in c code\n"); return 8848; } */ import "C" import "fmt" func main() { fmt.Println(C.dfs(C.check())) } 

 对每个单独的函数的执行流程大致已经清楚了,就不再关注单个函数了

以dfs函数为例,大概是

先call    main__Cfunc_dfs_abi0,

然后f7走到call    runtime_cgocall,

接着f7走到call    runtime_asmcgocall_abi0

最后f7才走到最喜欢的call    rax,大概是这么个流程

对于嵌套函数的参数传递,不像C的简单明了,直接放在rax,或者rdx中,(因为这里很简单)

 golang写在了内存中,最后是通过调用指针的方式读取,就算不free,也可能被覆盖,不太懂其内存机制

 (2290就是8848)

接下来我们看看go编写的dll,

package main import "C" import "fmt" //export touful func touful() { fmt.Println("this is in go-dll code") } func main() { } 

touful函数的作用只是输出,用c来调用一下

讯享网#include <windows.h> #include<stdio.h> #include<stdlib.h> typedef void (*TOUFUL)(); void DynamicUse() { HMODULE module = LoadLibrary("lib.dll"); if (module == NULL) { printf("加载DLLTest1.dll动态库失败\n"); return; } TOUFUL touful_me=(TOUFUL)GetProcAddress(module,"touful"); touful_me(); printf("动态调用"); } int main (){ DynamicUse(); return 0; } 

这是直接调试的dll代码,经典go的输出结构

 这是ida动调c程序的识别

 就算一直跟进,我也看不明白了,这全是指令,一个函数名也没有,本人能力有限,跟不下去了

总的来说,go和c的混合编程非常爽,太nb啦!!!

小讯
上一篇 2025-01-15 23:14
下一篇 2025-03-17 16:35

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/41810.html