网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
08月29日漏签0天
fx-es(ms)吧 关注:17,476贴子:312,879
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 1 2 3 下一页 尾页
  • 185回复贴,共3页
  • ,跳到 页  
<<返回fx-es(ms)吧
>0< 加载中...

ROP tutorial-使用fx-991/570ES+系列执行任意代码

  • 只看楼主
  • 收藏

  • 回复
  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
非常感谢来自Universal Casio Forum的@user202729 和SopaXorzTaker等等发现的方法以及他们撰写的教程。
此贴的目的是介绍ROP(基于返回指令的编程(?))以及如何在计算器上实现。
本贴部分内容来自Universal Casio Forum的英文教程,部分由我自己写成。
此贴更新周期可能较长,欢迎各位技术性补充。
(机翻+辣鸡英语警告)
(Warning:machine-translated English and broken English may appear below)
Special thanks to @user202729 , SopaXorzTaker and others from Universal Casio Forum for their methods and tutorials.
This post focuses on introducing ROP(Return-Oriented Programming) and how to do it on the fx-ES+ series calculators.
Some of the contents of this post is from the English tutorial from UCF,some are written by myself.
The updating cycle could be long,and welcome to add technical supplement.


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
更改:请把post改成thread...第一个跟帖竟然是改单词...
not "post",but "thread",sorry for my broken English :(


2025-08-29 03:20:06
广告
不感兴趣
开通SVIP免广告
  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
前置知识:
ACE(Arbitrary Code Execution 任意代码执行):指通过一些特殊技巧使系统执行自己编写的任意代码。 Using special skills to let the system execute custom code.
栈(stack):一种数据存储方式,特点是先进入的数据一定先出来。 A way to store data and the data enters it first must get out first.(broken English)
指针(pointer):一个存储着地址的变量,它会"指向"另一个变量(我也不知道这样讲对不对)。 A variable that "points to" another variable using the address it stores.


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
任意代码执行是我们的目标,这就是在这一系列计算器上"编程"的含义。
栈是我们操作的主要对象,通过基本溢出可以改变它的内容;
指针是我们的次要操作对象,通过它指向的各种指令和数据来运行自己的代码。


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
先来讲一讲堆栈吧~
为了和fx-ES+系列计算器使用的CPU(8位)相对应,我们假定所有数据都是16位长的。
什么是堆栈呢?嗯,你可以把它想象成一个书架,只是里面的"书"是横着放的:

左边的那些0x....代表这个格子的地址,右边代表的是地址里存储的内容("书")。
那个SP是堆栈指针(Stack Pointer),里面存放的数据是地址;它指向这一摞"书"的顶端(或者说,栈顶),也就是存储着栈顶的地址。
接下来需要引入两个指令:PUSH 和 POP。
PUSH指令的含义是把数据压入堆栈,具体是这么操作的:
先把数据从指定位置复制到[SP-1]指向的地址,再使SP的值-2,也就是栈顶升高了(放了新的"书",这一堆"书"的高度当然就变啦)
POP指令刚好和PUSH相反,它的含义是把数据弹出栈,也就是先复制数据送到指定的地方再使SP的值+2。


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
接下来是程序计数器(Program Counter),它也是一个指针,指向下一条要执行的指令的地址。这个指针就是我们修改的主要对象,ROP的三要素(PC,SP,片段)之一。只要能设法更改它的值,我们就能让CPU执行任何(可用)地址的指令。


  • 寂寞的人生啊t
  • TI-84+CE
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
他在github上的项目本机上我编译出来结果不一样)
而且可控缓冲区太小了无法执行长代码好像


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
@user202729 I am keeping learning ROP these days,can you pls tell me if I can make an infinity SETUP menu?I don't know what instructions are executed since I POP PC when the top of the stack is 1E 99 30 ?? (cs17 M+ 0 $). When I try to put the address into a loop,it just don't work...the loop is:
<46 chars>
F Ans cs17 M+ 0 $
(-) cs32 0 $
F Ans ^( cs32 0 $
<rest chars>
I think it should work like this:
Firstly I call 0:B660 and CPU executes:
B660:POP ER14 ;ER14=8B46(F Ans)
B602:POP PC ;PC=0:B65E
(now SP=8DAD or 8DAE?)
then it executes
B65E:MOV SP,ER14 ;SP=8B46
(Data in 8B46 is the same as that in 8D9E,the #46 char?)
B660:POP ER14 ;ER14=8B46(F Ans)
B662:POP PC ;PC=0:991E(cs17 M+ 0 $)
991E:....(codes showing menu)
then a POP PC instruction should be executed and it loops,but it seems to have NO POP PC...
Can you look up the disassembly and tell me which registers will be modified(?) and if it has a POP PC at the end of it?Thanks a lot.


2025-08-29 03:14:06
广告
不感兴趣
开通SVIP免广告
  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
-引入CALL,RETURN
在汇编程序里如何调用子程序呢?接下来讲一讲CALL、RETURN。为了对应,还是假设我们是在fx-ES PLUS的CPU上搞的吧~
CALL就是调用,这个指令的作用是把当前PC的值存到一个备份的寄存器里(在nX-U8/100里被称为LR(Link Register)),然后把要执行的下一条指令的地址赋给PC,这就实现了跳转(指向的指令往往是一个函数的开头,但是在ROP中我们往往让它指向即将结束的位置)。
RETURN是返回,它把LR里存储的内容(也就是跳转之前的地址)赋给PC,这就回到了调用的地方。
举个栗子:你走在回家的路上(走路回家-函数1),和你一道同行的好朋友每天都会在一个固定的地方买饮料(买饮料-函数2)。每一次路过街边那个小卖部,你都要站在门口(返回地址)等着他买饮料(程序流进行到函数2)。他买好了饮料,递给你一瓶表面凝结了水汽的冰镇可乐,你们就继续说笑着回了各自的家(回到函数1)。


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
-曾经的ACE实现方式
在那个遥远的年代,由于信息的不通畅、编写复杂程序的困难,程序员们没有像现在一样煞费苦心地防止其他人进行黑客活动。那时候只要想办法在内存中写入连续字节,再改变PC以让其指向这里就可以了,比如超级马里奥世界里的Credit Warp。


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

(使用Sprite List构成代码)

(坐标在内存中的形式)

(可能的指针)

(不同地址代表的指令)

(最终执行的代码)


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
-函数的跳转、返回(PUSH LR/POP PC)
除了CAL/RET之外,还有其他跳转/返回方式吗?有!我们还可以利用堆栈实现多级函数调用。
比如说下面的指令(下面的数字都是16进制的):
===========================================
0:2466 MOV R2,#3 ;寄存器R2被设为3
0:2468 BL 0:1234 ;在nX-U8中相当于call,即调用地址0:1234处的函数
;具体是这么操作的:先把PC的值存进LR(前面提到的备份寄存器)里
;再把PC设为新的地址(这里是0:1234)
0:246C MOV R0,#0 ;把R0设为0
---------------------------------------------------------------------
0:1234 ST R2,08124h ;把R2的值存入内存地址08124h
0:1236 RT ;即RETURN,把LR的值返回到PC里
===========================================
执行的效果是:
1.把R2设为3
2.把PC(0:246C)存至LR,然后把PC设为1234
3.把R2的值(3)存至地址08124
4.把LR值返回给PC,现在PC=246C
5.把R0设为0
请大家想一想,如果我在0:1234后面插入一个BL指令,再调用一个函数会发生什么?
对了,LR会被覆盖。举个栗子(example):
===========================================
0:1234 BL 0:3456 ;把目前PC存入LR,这就覆写了LR,此时LR=1236,然后PC=3456
0:1236 RT
---------------------------------------------------------------------
0:3456 MOV R0,#0 ;把R0设为0
0::3458 RT ;把LR赋给PC,此时LR值不变,PC变为1236
===========================================
PC变为1236时,问题出现了:0:1236处的指令也是RT(事实上不管是啥函数,用BL/B调用的注定会在结尾用RT返回),LR也是1236,这是个死循环!那咋办?用前文提到的PUSH/POP!我们在0:1234处放上一个PUSH LR,把LR值压入栈顶来备份LR,再调用0:3456;把0:1238的指令换成POP PC,即把栈顶的LR值弹出赋给PC,这样就能避免死循环了:
===========================================
0:1234 PUSH LR ;把LR压入栈
0:1236 BL 0:3456 ;把目前PC存入LR,这就覆写了LR,此时LR=1236,然后PC=3456
0:1238 POP PC ;把栈顶值(即备份的LR值)存入PC,此时PC为调用0:1234之前的PC值
---------------------------------------------------------------------
0:3456 MOV R0,#0 ;把R0设为0
0::3458 RT ;把LR赋给PC,此时LR值不变,PC变为1236
===========================================


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
-ROP的定义,如何实现
讲了那么多东西,现在终于可以引出ROP了...
ROP,即Return-Oriented Programming(面向返回的编程),其实是一种黑客攻击手法,利用漏洞覆写堆栈,劫持程序流,进而利用已有程序的片段(Gadgets)拼凑成自己的程序来实现任意代码执行。
这种攻击不好防范,但是实际操作极其硬核,需要事先知道目标设备的程序(以及它们的地址)来完成自己的“拼图”。这就是为什么在fx-es plus计算器上写“程序”看起来很难懂,因为输入的几乎全是地址!
来看一个最简单的例子:你想在屏幕上显示一个字母“A”,程序如下:
================
PRINT "A"
================
但是你并不能直接写代码,你有的只是一堆地址和别人写好的程序,所以真正写入的内容是堆栈:
EE 54 <-SP
31 ??
A8 8C
41 ??
EE 54
31 ??
A8 8C
04 ??
41 34
30 ??
57 B6
30 ??
这么一大片“天书”看起来非常吓人,但是实现的也就是显示一个A...
来看看原理:
首先POP PC,CSR:PC=1:54EE
然后执行那儿的函数,作用是弹出栈顶4字节赋值给XR0,此时ER0=8CA8,R2=41
函数返回时用的“恰好”是POP PC(实际上ROP就是要保证返回时用的POP PC,不然程序流就没法控制了),于是PC=1:54EE 把04赋给R2
接下来是0:3440,作用是显示ER0指向的地址里存的数据,以ASCII显示,显示R2行(即4行)。这里才是显示A的,前面都是铺垫。
最终是0:B656,作用是等待用户按下SHIFT,光标闪动。
看不懂?没关系,这里只是介绍ROP,让大家有个粗略的印象,不是正式的讲解。在以后的帖子中我们会详细地分析ROP的执行过程的(抄user202729的教程)。
顺带一提上面的代码就是570+/991+的ROP,可以直接运行,按键如下:
<出原式后先随便输入52个字符>
cv24 M 1 $
3√ Ran# A $
cv24 M 1 $
3√ Ran# cs04 $
A 4 0 $
! cs32 0 $
<剩下的随便打>
注:$代表可以随便输入的字符,3√代表立方根,cs代表科学常数,cv代表单位转换。A就是变量A。如果想在按下SHIFT后不死机,建议在! cs32 0 $后面加上log √ 0 $
相信大家已经看出端倪了,log √是条码拼字的控制字符。没关系,讲完寄存器我们就正式开始介绍CASIO ROP。


  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
16楼的解释及ROP hackstring有误,更正一下:
堆栈:(为了省空间,2个字(word)排成一行)
EE 54 31 ??
A8 8C 41 ??
6A 27 30 ??
EE 54 31 ??
A8 8C 04 ??
41 34 30 ??
57 B6 30 ??
上次漏掉的6A 27 30 ??代表把R2的内容写入ER0指向的地址,就是说把41写入[8CA8],因此16楼的hackstring并不能在左上角显示A(其他地方有没有我就不知道了)。
修正的办法是在16楼的hackstring的3√ Ran# A $后面插入 ∫( cs23 0 $。


2025-08-29 03:08:06
广告
不感兴趣
开通SVIP免广告
  • 生姜一片jj
  • TI-84+
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
>堆栈指针(SP):这个16位宽的寄存器指向栈顶,在它指向的位置下方都可以被看做堆栈。由于栈操作都是以字(Word)为单位的,所以使用POP、PUSH指令改变栈指针时,如果弹出/压入了奇数字节,核心会自动插入一个空周期(不弹出/写入至任何位置)。注意SP没有自动字对齐功能,所以如果它被设为奇数,那在不直接写入的情况下它会一直是奇数。
>数据访问寄存器(EA):我也不知道它的全称,但是这个16位宽的寄存器的作用是访问数据存储空间的,也就是说,数据存储空间和程序存储空间是分开的!这是提升稳定性和防止黑客攻击的常规操作,现代绝大多数的CPU都是这么设计的,也是ROP存在的意义。它可以和数据字段寄存器(DSR)一起凑成24位宽的地址,提供256x64kb的超大寻址空间。


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 1 2 3 下一页 尾页
  • 185回复贴,共3页
  • ,跳到 页  
<<返回fx-es(ms)吧
分享到:
©2025 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示