Re: [问题] 函式的参数

楼主: Killercat (杀人猫™)   2014-06-18 04:39:56
edit:由于x64下cdecl会学fastcall把特定型别的args放register去传
所以这问题应该是无解。
简单的说,以下方的code为例子,根本不可能拿到正确的&a
编译器在发现你试图取址a/b的时候 会把他们从esi/edi(都是x64的register)
拷贝出来以后随意丢在一个无法预期的位置让你去取址
以这边来讲,就是丢一个离function frame stack 16byte的位置
所以本题应该是无解,而且当args不是int的时候他传法不见得会相同
重点asm放在这给大家参考一下
movl $30, %esi
movl $20, %edi
call _Z8testCallii
作者: chuckAI (心的方向)   2014-06-18 09:25:00
谢谢 killer大 虽然很多专业名词看不懂 但文中的意思是原宣告的参数a,b 位置会有offset的现象 但会随着硬件有所不同.. 我这样的理解应该是对的吧..
楼主: Killercat (杀人猫™)   2014-06-18 09:50:00
简单的说 a b都会跟__builtin_frame_address有一段固定的距离 你可以试试看用这段距离去取值但是我不知道他因为什么而不同就是
作者: Jockey66666 (往事已成追忆)   2014-06-18 11:21:00
好文
作者: AstralBrain   2014-06-18 13:48:00
你的测试环境是linux x64吧, int应该会用register传a本来放在rdi, b在rsi因为你要取址, compiler才在stack上随便找个地方放a,b要放在哪里已经不归calling convention管了
楼主: Killercat (杀人猫™)   2014-06-18 14:18:00
所以gcc会因为我执行__builtin_frame_address(0)所以随便找一个地方先把arg stack dump出来吗? 好诡异的行为
作者: AstralBrain   2014-06-18 14:22:00
因为你要&a, 所以把a从rdi搬到stack上
楼主: Killercat (杀人猫™)   2014-06-18 14:27:00
我懂了 你是说他在compile time发现我要对a取址所以会多作一些额外的行为,把他从真正的frame stack搬出来对吧?因为就我理解用register传应该只有fastcall会这样玩...我回去试试看用别的型别 感谢欸 仔细看了一下 -S 你是对的 不过我这边是放esi/edi
作者: AstralBrain   2014-06-18 14:32:00
x64因为多了一大堆register, 前几个参数会跟fastcall一样用register传
楼主: Killercat (杀人猫™)   2014-06-18 14:33:00
了解 看了一下.s的确也是如此.... 感谢!
作者: AstralBrain   2014-06-18 14:36:00
rsi/rdi是笔误XD int是32bit所以会用e开头的register
楼主: Killercat (杀人猫™)   2014-06-18 14:46:00
不过这样说的话 其实本来问题应该是无解了...因为型别不同他会用不同方法去传 很伤脑筋
作者: AstralBrain   2014-06-18 14:58:00
所以交给gdb去捞debug symbol又快又方便 XD
作者: azureblaze (AzureBlaze)   2014-06-18 15:08:00
http://ideone.com/P2QxLN 印参数从caller比较简单吧..
楼主: Killercat (杀人猫™)   2014-06-18 15:08:00
可是request是说要从callee... 所以才有这篇文章囧
作者: azureblaze (AzureBlaze)   2014-06-18 15:15:00
我觉得他不见得只能改callee,可能只是想偏了...如果型态不定数量不定那麻烦事还更多没reflection做这种事吃力不讨好
楼主: Killercat (杀人猫™)   2014-06-18 15:17:00
callee确定是不可行的了 这年头连直接对frame stack hack的最后希望都没了 还能怎么搞 :D大概就剩下Astral说的拿debug symbol拖出来鞭尸了

Links booklink

Contact Us: admin [ a t ] ucptt.com