This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
#life 好了,都 810 了,本来打算多讲会事的,明天再吧,因为我得写点名器了... which 之前已经设计好的,至少比那些易语言党强的可扩展可定制性...
今天讲之前那个 x86 汇编的 helloworld 为什么出问题吧... 讲完再写不影响的,我已经基本会简单的 Qt 了... 就是我还看不到内存泄漏溢出、悬垂指针(Use-after-free)和非线程安全的风险
duangsuse::Echo
今天讲之前那个 x86 汇编的 helloworld 为什么出问题吧... 讲完再写不影响的,我已经基本会简单的 Qt 了... 就是我还看不到内存泄漏溢出、悬垂指针(Use-after-free)和非线程安全的风险
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
今天讲之前那个 x86 汇编的 helloworld 为什么出问题吧... 讲完再写不影响的,我已经基本会简单的 Qt 了... 就是我还看不到内存泄漏溢出、悬垂指针(Use-after-free)和非线程安全的风险
讲完再写个 ARMv7 glibc (arm_v7-unknown-linux-gnu) #llvm #sysadmin #recommended #binary #backend
(arch_subarch-vendor-os-abi-objectfmt) where
arch: CPU 解释器平台,如 ARM、x86、x86_64、SPARC
编译到原生代码的语言,诸如 C/C++ 需要程序员时刻考虑底层的实现细节,诸如硬件解释器平台
一般来说不同的硬件处理器((嵌入式)微控制器)平台有不同的 ISA(指令结构,Instruction Structure Architude)和解释器体系结构,与其他平台差异很大
所有代码被翻译成由 0(低电位)和 1(高电位)组成的,一定大小的二进制数字(如 0101、1111)组合成的一定长度的单元(必须是 2 的整数倍,一般最小为 8 位二进制数字)「字节序列」
然后被机器处理器按程序计数器(指令指针)进行取指令、解码逻辑分派、执行
就是说不同的平台之间有实现差异,举个例子来说,ARM 系列的 RISC(精简指令集系处理器)就只能使用
好吧我承认上一个例子是不好的,再举个例子,ARM 机器有
上面的看不懂没有关系... 因为这些知识还不是系统的,有太多涉及你们可能不知道的知识,而我也不写例子所以大概是一脸蒙蔽
因为我现在不是讲这个...
subarch: CPU 解释器子平台,如 ARMv7、ARMv8
举个例子,有些版本的 ARM 处理器(比如 ARMv6-M)有
所以 ARMv6 处理器就不能执行(或者不能很好的支持)有这些指令的 ARMv6-M 代码(指令序列)
ARMv6-M 程序员手册
ARMv7-M 程序员手册
我忽略了其他的一些平台差异,诸如字节序(大端/小端)、寄存器集合、浮点实现、子平台特性(诸如 AVX、SSE、NEON)等
vendor: 生产厂家类型,如 SUSE、PC、Apple、NVIDIA
不说了... 都知道,我们一般都是 PC 或者 unknown
os: 操作系统平台,如 Linux、OpenBSD、Win32
一般都是 win32 或者 Linux
这里有个容易混淆的地方是 win32 是一个平台,包括 32 位和 64 位 Windows,从 Windows 3.1(第一个使用 NT 内核的 Windows 版本开始)就叫 win32 了
Windows 的 64 位版本里 Win32 支持貌似叫 WOW64(Windows on Windows64)
abi: 程序二进制(底层运行环境)接口,如 GNU glibc、MSVC、Android、Musl
Musl 貌似是部分兼容 Glibc 的,一般用于嵌入式开发
Glibc 是很传统的 Unix-like 系统 C 语言基础库,老的闭源 libc 的替代者
MSVC,M$ VisualC (runtime?) msvcrt*.dll,类似 Glibc
ABI 是应用程序到操作系统交互的一栋桥梁。很少有人不使用 libc 开发应用程序,当然你用汇编
objectfmt: 对象文件格式,如 COFF、ELF、MachO
常用 ELF,Extesible Library Format,可扩展库格式,它也是基于 COFF,Linux 很早就给予其内建支持了
MachO 是苹果 Darwin(OS X(这个 X 是罗马数字 10,读 "ten"))用的可执行文件格式,妈的在我这里 Linux 环境里处理起来好麻烦啊
ABI 的吧... 虽然都是很简单的程序而已,连分支都没有用到
(arch_subarch-vendor-os-abi-objectfmt) where
arch: CPU 解释器平台,如 ARM、x86、x86_64、SPARC
编译到原生代码的语言,诸如 C/C++ 需要程序员时刻考虑底层的实现细节,诸如硬件解释器平台
一般来说不同的硬件处理器((嵌入式)微控制器)平台有不同的 ISA(指令结构,Instruction Structure Architude)和解释器体系结构,与其他平台差异很大
所有代码被翻译成由 0(低电位)和 1(高电位)组成的,一定大小的二进制数字(如 0101、1111)组合成的一定长度的单元(必须是 2 的整数倍,一般最小为 8 位二进制数字)「字节序列」
然后被机器处理器按程序计数器(指令指针)进行取指令、解码逻辑分派、执行
就是说不同的平台之间有实现差异,举个例子来说,ARM 系列的 RISC(精简指令集系处理器)就只能使用
load/store 指令访问内存,而 x86 系列的 CISC(传统的复杂指令系处理器)很大一部分指令都可以访问内存,典型的方式是使用 effective address(迫真?)(实际上,我还不记得 ARM 系列一般都有哪几种参数寻址方式)好吧我承认上一个例子是不好的,再举个例子,ARM 机器有
j 指令用于跳转(设置程序计数器来实现类似 Java goto 一样的功能),而 x86 里这是 jmp 指令,你看字面上都不一样所以他们是不能直接互相兼容的,换句话说就是「x86 机不能直接解释 ARM 的指令字节序列,而 ARM 也不能直接解释 x86 的指令字节序列」上面的看不懂没有关系... 因为这些知识还不是系统的,有太多涉及你们可能不知道的知识,而我也不写例子所以大概是一脸蒙蔽
因为我现在不是讲这个...
subarch: CPU 解释器子平台,如 ARMv7、ARMv8
举个例子,有些版本的 ARM 处理器(比如 ARMv6-M)有
DMB DSB ISB 这种(码位控制)指令,而有些没有(诸如 ARMv6)所以 ARMv6 处理器就不能执行(或者不能很好的支持)有这些指令的 ARMv6-M 代码(指令序列)
ARMv6-M 程序员手册
ARMv7-M 程序员手册
我忽略了其他的一些平台差异,诸如字节序(大端/小端)、寄存器集合、浮点实现、子平台特性(诸如 AVX、SSE、NEON)等
vendor: 生产厂家类型,如 SUSE、PC、Apple、NVIDIA
不说了... 都知道,我们一般都是 PC 或者 unknown
os: 操作系统平台,如 Linux、OpenBSD、Win32
一般都是 win32 或者 Linux
这里有个容易混淆的地方是 win32 是一个平台,包括 32 位和 64 位 Windows,从 Windows 3.1(第一个使用 NT 内核的 Windows 版本开始)就叫 win32 了
Windows 的 64 位版本里 Win32 支持貌似叫 WOW64(Windows on Windows64)
abi: 程序二进制(底层运行环境)接口,如 GNU glibc、MSVC、Android、Musl
Musl 貌似是部分兼容 Glibc 的,一般用于嵌入式开发
Glibc 是很传统的 Unix-like 系统 C 语言基础库,老的闭源 libc 的替代者
MSVC,M$ VisualC (runtime?) msvcrt*.dll,类似 Glibc
ABI 是应用程序到操作系统交互的一栋桥梁。很少有人不使用 libc 开发应用程序,当然你用汇编
syscall 手动调用内核函数并且自己写 ldscript(开发更底层的程序的时候可能用得到,比如链接内核、内核模组(模块)什么的)就算了objectfmt: 对象文件格式,如 COFF、ELF、MachO
常用 ELF,Extesible Library Format,可扩展库格式,它也是基于 COFF,Linux 很早就给予其内建支持了
MachO 是苹果 Darwin(OS X(这个 X 是罗马数字 10,读 "ten"))用的可执行文件格式,妈的在我这里 Linux 环境里处理起来好麻烦啊
ABI 的吧... 虽然都是很简单的程序而已,连分支都没有用到
GitHub
llvm/Triple.h at master · llvm-mirror/llvm
Project moved to: https://github.com/llvm/llvm-project - llvm/Triple.h at master · llvm-mirror/llvm
duangsuse::Echo
讲完再写个 ARMv7 glibc (arm_v7-unknown-linux-gnu) #llvm #sysadmin #recommended #binary #backend (arch_subarch-vendor-os-abi-objectfmt) where arch: CPU 解释器平台,如 ARM、x86、x86_64、SPARC 编译到原生代码的语言,诸如 C/C++ 需要程序员时刻考虑底层的实现细节,诸如硬件解释器平台 一般来说不同的硬件处理器((嵌入式)微控制器)平台有不同的 …
... 再附加上一个 DalvikVM 的 smali 汇编猜数游戏吧,然后教你们怎么用 enjarify、dex2jar 之类的(2333
jadx、jd-gui 什么的那种简单到爆炸的玩意就不教你们了,你用脚趾头都想得出来怎么用啊?
最后附上一句:我是擅长逆向工程的(迫真)(hhhh 开什么玩笑....
jadx、jd-gui 什么的那种简单到爆炸的玩意就不教你们了,你用脚趾头都想得出来怎么用啊?
最后附上一句:我是擅长逆向工程的(迫真)(hhhh 开什么玩笑....
duangsuse::Echo
讲完再写个 ARMv7 glibc (arm_v7-unknown-linux-gnu) #llvm #sysadmin #recommended #binary #backend (arch_subarch-vendor-os-abi-objectfmt) where arch: CPU 解释器平台,如 ARM、x86、x86_64、SPARC 编译到原生代码的语言,诸如 C/C++ 需要程序员时刻考虑底层的实现细节,诸如硬件解释器平台 一般来说不同的硬件处理器((嵌入式)微控制器)平台有不同的 …
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
... 再附加上一个 DalvikVM 的 smali 汇编猜数游戏吧,然后教你们怎么用 enjarify、dex2jar 之类的(2333 jadx、jd-gui 什么的那种简单到爆炸的玩意就不教你们了,你用脚趾头都想得出来怎么用啊? 最后附上一句:我是擅长逆向工程的(迫真)(hhhh 开什么玩笑....
贼推荐 JVM 开发者学学如何使用 JVM 系平台上的 IL(中间表示)编程,这样你起码知道值类型装箱是啥(迫真,JVM 真的有值类型?,Java 好像是没有但是 JVM 可能有)
并且虽然 Java 反编译器多,有时候碰到反编译失败的起码你能看两行是吧,就是如果不会脱壳、分析虚拟壳机什么的就比较淡疼,但总比啥都不知道强啊!
因为你好歹是看到了 DalvikVM 里那 16 个虚拟对象寄存器... 顺推 Smalidea,支持 Smali IDEA 调试,还能调试动态分析 Android 应用
... 反正就是比对 Dalvik 一无所知强啊,虽然你是 Android 的应用层程序员,但是工作十几年不知道啥是 DalvikVM 有点可悲了...(绝望)
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩
并且虽然 Java 反编译器多,有时候碰到反编译失败的起码你能看两行是吧,就是如果不会脱壳、分析虚拟壳机什么的就比较淡疼,但总比啥都不知道强啊!
因为你好歹是看到了 DalvikVM 里那 16 个虚拟对象寄存器... 顺推 Smalidea,支持 Smali IDEA 调试,还能调试动态分析 Android 应用
... 反正就是比对 Dalvik 一无所知强啊,虽然你是 Android 的应用层程序员,但是工作十几年不知道啥是 DalvikVM 有点可悲了...(绝望)
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
#telegram 100 Members Thank U!
Old Pin <<<
duangsuse::Echo
pinned «我如何评价 @duangsuse: 「代码一行不写,废话一大堆」 — duangsuse»
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
hello.S .section .rodata hello_world: .string "你好,世界!\n" .section .text .globl _start _start: call main # call assembly main mov $60, %rax # sys_exit mov $0, %rdi # exit status syscall # make call sysprintf: mov %rsp, %rbp # stdcall…
就是这个... 咳咳 #CS #PL #backend #sysadmin #os #system
嗯... 很抱歉花太多时间了没时间所以不能讲好,而且对于 x86 的执行栈维护我也有点懵懵懂懂的样子,感觉稍微好点了但还是比较弱鸡,大佬轻喷啊
刚才想尝试一下 intel 风格的汇编,结果是个大坑...(我还不习惯 intel 风格的汇编...) 气死,第一次尝试待会发图
x86 系列汇编语言简单文档
x86 CDECL C 语言函数调用约定(规范)
好耶,那么开始说,首先是问题所在
我们来 cosplay CPU 一行一行的执行指令序列:
现在有一个
start:
call main ; push rip, save ret_addr to [rsp..rsp - size]
main:
mov rbp = rsp
现在程序的执行栈是这样的
> rsp: 0x.......
> [rip @ start:2nd]
> rbp: rsp
mov rax = hello_world
rax: dword ptr to hello_world @ .rodata
; 我们 skip 掉 dec rax
push rax
; [rip @ start]
; [dword ptr to hello_world @ .rodata]
push 20
; [rip @ start]
; [dword ptr to hello_world @ .rodata]
; [imm number 20]
call sysprintf
; [rip @ main]
sysprintf:
mov rbp = rsp
rbp: rsp ; 注意,上一次的 rbp 值压根没有被保存!
mov rax = 1
mov rdi = 1
> rip @ _start
> dword ptr to hello_world @ .rodata
> imm number 20
> rip @ main
pop rsi ; ... 由于程序正常允运行(真的?),我们只能假设 ret_addr 被无视了
rsi: imm number 20
pop rdx
rdx: dword ptr to hello_world ; 意料之外?
syscall
ret
.... 我模拟不下去了,算了算了 x86 这个我目前也要花很多时间学习下次再说(逃跑
... 我真应该做个动画帮助理解,像 RednaxelaFX 同学一样
嗯... 很抱歉花太多时间了没时间所以不能讲好,而且对于 x86 的执行栈维护我也有点懵懵懂懂的样子,感觉稍微好点了但还是比较弱鸡,大佬轻喷啊
刚才想尝试一下 intel 风格的汇编,结果是个大坑...(我还不习惯 intel 风格的汇编...) 气死,第一次尝试待会发图
x86 系列汇编语言简单文档
x86 CDECL C 语言函数调用约定(规范)
好耶,那么开始说,首先是问题所在
我们来 cosplay CPU 一行一行的执行指令序列:
现在有一个
.rodata 节的 hello_world 符号大概 20 字节的零结字符串(asciz,或者 string \0)已经被映射好了start:
call main ; push rip, save ret_addr to [rsp..rsp - size]
main:
mov rbp = rsp
现在程序的执行栈是这样的
> rsp: 0x.......
> [rip @ start:2nd]
> rbp: rsp
mov rax = hello_world
rax: dword ptr to hello_world @ .rodata
; 我们 skip 掉 dec rax
push rax
; [rip @ start]
; [dword ptr to hello_world @ .rodata]
push 20
; [rip @ start]
; [dword ptr to hello_world @ .rodata]
; [imm number 20]
call sysprintf
; [rip @ main]
sysprintf:
mov rbp = rsp
rbp: rsp ; 注意,上一次的 rbp 值压根没有被保存!
mov rax = 1
mov rdi = 1
> rip @ _start
> dword ptr to hello_world @ .rodata
> imm number 20
> rip @ main
pop rsi ; ... 由于程序正常允运行(真的?),我们只能假设 ret_addr 被无视了
rsi: imm number 20
pop rdx
rdx: dword ptr to hello_world ; 意料之外?
syscall
ret
.... 我模拟不下去了,算了算了 x86 这个我目前也要花很多时间学习下次再说(逃跑
... 我真应该做个动画帮助理解,像 RednaxelaFX 同学一样
duangsuse::Echo
就是这个... 咳咳 #CS #PL #backend #sysadmin #os #system 嗯... 很抱歉花太多时间了没时间所以不能讲好,而且对于 x86 的执行栈维护我也有点懵懵懂懂的样子,感觉稍微好点了但还是比较弱鸡,大佬轻喷啊 刚才想尝试一下 intel 风格的汇编,结果是个大坑...(我还不习惯 intel 风格的汇编...) 气死,第一次尝试待会发图 x86 系列汇编语言简单文档 x86 CDECL C 语言函数调用约定(规范) 好耶,那么开始说,首先是问题所在 我们来 cosplay…
This media is not supported in your browser
VIEW IN TELEGRAM
... 就是这样,反正 cdecl 还是没理解嘛,不过要我写个不用调用函数单 syscall 的我会写...
cdecl 执行栈管理,反正 edb 调试就是出各种问题,指针都乱套了,想在 rsp 上
今天晚上不可能了
cdecl 执行栈管理,反正 edb 调试就是出各种问题,指针都乱套了,想在 rsp 上
add sub 总是出问题,该 pop 到好东西的时候永远 pop 到无效(没有内存页面分配到的)指针今天晚上不可能了
.section .rodata... 比较难受,总是 segv,上 edb 以后发现是
hello: .asciz "hello, world!"
.globl _start
_start:
mov %rsp, %rbp
call main
doPrint:
pop %rdx
pop %rsi
mov $1, %rax
mov $1, %rdi
syscall
ret
doExit:
mov $0, %rax
call _Exit
main:
push $10
push hello
call doPrint
jmp doExit
ret @ main 跳转到 0xa 这个地址去了,而这块内存根本还没有 map 到... call Push 到栈上的应该是根本不可能是无效 rip 地址啊...今天这个汇编的算了... 很扫兴,也块到明天了
Makefile:
ASM_LDFLAGS := -lc -I /usr/lib64/ld-2*.so
hello: hello.S
$(AS) $(ASFLAGS) $^ -o $@.o
$(LD) $(LDFLAGS) -o $@ $@.o $(ASM_LDFLAGS)
clean:
$(RM) hello hello.o
run: hello
@./hello
runclean: run clean
.PHONY: clean run runclean