Jump to content



Photo
* * * * * 6 votes

FX-82/-83GT/-115/-991ES PLUS Hacking


  • Please log in to reply
515 replies to this topic

#321 .kklicker

.kklicker

    Newbie

  • Members
  • Pip
  • 1 posts

  • Calculators:
    Casio fx-92 Ver A

Posted 03 February 2018 - 07:41 AM

Hello,
I'm the (un)happy owner of a (casio,obvs) fx-92 Ver A calculator which is the french/belgian version of the fx-82 series.
As I told @SopaXorzTaker in the chat, I know quite a few things in the binary exploitation field(On PCs but also some embedded devices).

I'm following the topic since a while (like the first page) so I was wondering if I could join/eventually try to help and maybe try to adapt the exploits already found to my calculator model  -I don't know if it uses the same chipset atm, I hope so- because the firmware is different and a bit limited compared to fx-82's functions.
(I yet found what I think could be an exploitable buffer overflow, gonna try to read and search about the arch when I get time)


Edited by .kklicker, 03 February 2018 - 07:46 AM.


#322 nm111

nm111

    Newbie

  • Members
  • Pip
  • 1 posts

Posted 14 February 2018 - 09:29 AM

Hi,

I think what you're doing here is quite cool, so I've made an account to join in. Do you know what I could do to try and help?

I heard you need a wiki, and I found a good site called wiki-site.com. I have made a wiki there: http://casiohacking.wiki-site.com/. You can make an account on that site and you should be able to create pages.



#323 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 23 February 2018 - 01:54 PM

Use a Markdown viewer to view this.

 

# Tutorial
 
## Stack
 
The stack is used for static memory allocation. Read Wikipedia: https://en.wikipedia.org/wiki/Stack-based_memory_allocation
 
Short explanation:
 
* When a function need an amount of memory, it decreases the stack pointer (SP) by that many bytes, and own the memory pointed to by SP.
* When a function no longer need that memory, it increases the stack pointer.
 
## Function call
 
For the nX/U8 core, when a function calls another functions, the address of the caller is stored in the `LCSR:LR` register, and the arguments are (often) stored into the registers `R0-R15` (and occasionally pushed on the stack, although I can't recall any example right now).
 
For example, if the function `f` taking 1 1-byte argument in `r2`, has the structure
 
    0:1234    st    r2, 08124h
    0:1236    rt
 
and a snippet of code
 
    0:2466    mov    r2, #3
    0:2468    bl     0:1234h
    0:246c    mov    r0, #0
 
is executed, the following will happen:
 
* At `0:2466`, `r2` is set to decimal value `3`.
* At `0:2468`, when the command `bl 0:1234h` is called,
    * The `LCSR:LR` register value is set to `0:246ch` (the address of the command right after the `bl` command) (that is, `LCSR = 0` and `LR = 246ch`)
    * The `CSR:PC` register value is set to `0:1234h`.
* Next, `0:1234` is executed.
* After 1 command, at `0:1236`, when the `rt` command is called, the value of `CSR:PC` is set to the value of `LCSR:LR` (which is `0:246ch`).
 
* Then, the command `0:246ch` is executed.
 
-------
 
## Recursive function
 
Next. When a function `a` that is called by another function `parent` needs to call yet another function `child`, it needs to remember the value of `LCSR:LR` when it was called (by `parent`). That is done by the command
 
    push lr
 
which allocates 4 bytes of memory on the stack, and store the value of `lcsr` and `lr` there.
 
When the function returns, instead of
 
    pop lr
    ret
(which is supposed to return the value of `lr` and `lcsr` and then do the normal return), it executes
 
    pop pc
.
 
For more detailed instruction, read the nX/U8 core instruction manual. But basically, the LR (2 bytes) is on the top, then the LCSR (1 byte), then an unused byte.
 
Note that, although the CPU allows up to 16 code/data segments, the calculators only uses 2 segments, so only the least significant bit of `lcsr` is important, all other bits are always 0. Moreover because of word alignment of `PC`, the least significant bit of the PC is always zero.
 
--------
 
So, how does that help with arbitrary code execution?
 
As we observed, there are a lot of `pop pc` commands in the code. And those commands set the program counter to whatever on the top of the stack. Therefore, if we executes a `pop pc` command and can control what is in the stack, we can make the PC to jump to arbitrary location.
 
The remaining problem is to write a program in ROP.
 
---------
 
### Example
 
For an example, let's try understanding the hackstring that was used to understand how **F030** worked, taken from [#286](http://community.casiocalc.org/topic/7583-fx-82-83gt-115-991es-plus-hacking/?p=61257).
 
Note that you should lookup the command in the disassembly listing of the 570es+/991es+ ROM to understand what I'm saying.
 
    <from #52 character> cv24 M 1 - 0 cv26 X - Int cs23 0 - cv24 M 1 - 0 cv26 cs4 - A 4 0 - ! cs32 0 -
 
First, convert it to hexadecimal for ease of understanding. You know where to look for a character table, for example you can use the Javascript code in [#301](http://community.casiocalc.org/topic/7583-fx-82-83gt-115-991es-plus-hacking/page-8#entry61330).
 
    ?? ?? ?? ... (there are 52 bytes) ... ?? ?? ??
    ee 54 31 ?? 30 f0 58 ?? 6a 27 30 ??
    ee 54 31 ?? 30 f0 04 ?? 41 34 30 ?? 57 b6 30 ??
 
The values of `??` are not important, the behavior of the hackstring is the same for all (non-null) values of `??`.
 
And what does this hackstring do?
 
First, the 100-byte hackstring is repeated in the memory, from the input area (`8154h`) to the end of the writable memory (`8e00h`).
 
(for more information why does that happen, basically a `strcpy(0x81b8, 0x8154)` get called, and all the 100 bytes inside the `0x8154..0x81b8` ranges (includes `0x8154`, excludes `0x81b8`) are not null; and the `strcpy` in the calculator is implemented like this: (pseudo-code)
 
    void strcpy(char* dest, char* src) {
        while (*src != NULL) {
            *dest = *src;
            ++dest;
            ++src;
        }
    }
 
Fortunately there are some non-writable (and so they're always null) memory in the range `0x8e00..0xefff`, so that doesn't loop forever.
 
)
 
That is, the byte at `8154h` has the value of the first byte in the hackstring, the byte at `8155h` has the value of the second byte in the string, ..., the byte at address `x` (`8154h <= x < 8e00h`) has the value of the `(x - 8154h) mod 100` (0-indexing) byte in the hackstring.
 
Then, (eventually) when the `PC` is at address `0:2768h`, `LR = 0:2768h` and `SP = 8da4h`. As you can calculate, the 4 bytes at address `8da4h .. 8da7h` has the values of the `52 .. 55`th bytes of the hackstring. (0-indexing) Now the 4 bytes `ee 54 31 ??` are on the top of the stack.
 
When the `pop pc` command is executed, `pc = 54eeh` and `csr = 1`. (remember the endianness)
 
When the command at `1:54eeh` is executed, `er0 = 0f030h` and `r2 = 58h`.
 
... hopefully you can deduce what will happen next, at least until the command `0:154f0h` is executed the second time. You should be able to figure out that the top of the stack at that time is
 
    41 34 30 ?? 57 b6 30 ??
.
 
--------
 
To understand the remaining 8 bytes of the hackstring, you need to know about some function addresses.
 
First, remember that a function which calls another function must start with `push lr` (there may be some commands that does not change `lr` before that) and ends with `pop pc`. So, if we make the `pc` be right after the `push lr` command, eventually a `pop pc` would be executed with the same `sp`, and the 4 bytes on the top of the stack is not changed (assume the function really want to returns to its caller). That way we can continue to keep control of the `pc`.
 
So, some useful functions in the calculator:
 
* `0:343eh`: A function, given an address pointed to with `er0`, and a number `r2`, print `r2` lines on the screen using the string pointed to by `er0`.
* `0:b654h`: A function taking no parameter, returning no parameter (i.e., `void f(void)`, blinks the cursor and waits for the user to press the key `shift` before returning.
 
--------
 
So 8 bytes
 
    41 34 30 ?? 57 b6 30 ??
 
(in the above hackstring) calls those two functions in order.
 
Note that I just mentioned the multiline print function is at `0:343eh`. Why using the bytes `41 34 30`? (so that `pop pc` set the `pc` to `0:3431`?
 
First, the actual command executed is at `0:3440`, because of word alignment, the value of `pc` is always even. (not so for `sp`, be careful!)
 
Now assume we set the `pc` to `0:343e`. It will push the value of `lr` on the top of the stack, and then execute some commands until `0:3478`, and then set the value of `pc` to the value of `lr` we pushed earlier. Which is not what we want. (as we can't set the `lr` to a desired value) That's also the reason why we don't like gadgets ending with `ret`. 
 
Instead, we jump to the command **right after** the `push lr`. That way the `pop pc` will pop the top of the stack at that time, and we can control the value of `pc`. 
 
(some notes regarding this:
 
(Summary: jumps to the command right after `push lr` is always correct, but other options may also be correct)
 
1. If we jump to a command before the `push lr`, the `pc` will often jump to some unexpected places, as the command right before `push lr` is often `pop pc` or `ret`.
2. If we jump to the `push lr` command, the value of `pc` after the corresponding `pop pc` will depends on the value of `lr` at the start of the function. Only useful if we can control the value of `lr`.
  A similar situation happen if we jump to the beginning of (or inside) a function returning with `ret` - we need to control the value of `lr`.
3. If we jump to the command right after the `push lr` the function is executed and the corresponding `pop pc` will pop the top of the stack. Good.
4. If we jump to some position after the `push lr` the function body is executed except some commands at the first.
 
Typically, option (3) is used because it's the simplest, but occasionally option (2) or (4) should be used instead if typing them into the calculator takes significantly less keystrokes. I will (try to) explain this part later if some hackstring uses that.
 
)
 
---------
 
## Loops
 
Next, about loops.
 
The only way to loop in return-oriented programming is to modify the value of the stack pointer `sp`. If you search for `sp` in the disassembly, you can see that the only commands modifying `sp` and is sufficiently near a (later) `rt` or `pop pc` (such that we can easily reason about what will happen if those commands (between the command modifying `sp` and the return command) is executed) are:
 
* `mov sp, er14` (often followed by `pop er14` and `pop pc`)
* `add sp, #...` (positive amount means pop that many bytes from the stack)
 
Only the first one is (currently) used for looping.
 
So, to loop we should:
 
* When `sp = A`, and a `pop pc` command is executed, execute something that doesn't modify the stack.
* Execute a gadget with `pop er14; pop pc` and put `A-2` on the top of the stack.
* Execute a gadget with `mov sp, er14; pop er14; pop pc`.
 
(it's possible to loop with something that does modify the stack, more information later)
 
When the last gadget `mov sp, er14; pop er14; pop pc` is executed, the following happens:
 
* `mov sp, er14`: `sp` is set to the value `A - 2`.
* `pop er14`: `sp` is increased by `2` bytes. `er14` contains whatever in that 2 bytes.
* `pop pc`: `pc` has the value at `A`.
 
This is an infinite loop. I have never written a conditional statement/loop, but it should be possible with some table lookup/etc.
 
--------
 
### Example:
 
Using the hackstring in [#290](http://community.casiocalc.org/topic/7583-fx-82-83gt-115-991es-plus-hacking/page-8#entry61301):
 
    <52 characters> cv24 M 1 - Fvar cv26 cv40 - Int cs23 0 - tan-1 D 0 - cs26 cv26 cs16 D 1 - cv12 = 0 - sin 2 0 - 0 cv34 Int cs23 0 - (-) cs32 0 - frac Ans ^ cs32 0 - <2 remaining characters>
 
Hexadecimal:
 
    ?? ... (52 bytes) ... ??
    ee 54 31 ?? 46 f0 fe ?? 6a 27 30 ?? b2 44 30 ?? 40 f0
    1d 44 31 ?? e2 3d 30 ?? a0 32 30 ?? 30 f8
    6a 27 30 ?? 60 b6 30 ?? ae 8b 5e b6 30 ??
    ?? ??
 
Only the 10 last bytes are related to looping.
 
`60 b6 30 ??` corresponds to the address `0:b660h`. The commands from `0:b660h` to `0:b662h` are executed.  
Then, `ae 8b` is popped into `er14`. (that is, `8baeh`)  
`5e b6 30 ??` corresponds to the address `0:b65eh`. The commands from `0:b65eh` to `0:b662h` are executed, effectively jumps to the start of the loop.
 
> There are a lot of `mov sp, er14; pop er14; pop pc` command sequences. Choose one that you find typing most easily.
 
--------
 
## Loops which modifies the stack
 
What is "modify the stack" and what is "not modify the stack"? This is pretty self-explanatory.
 
Note:
 
* A `pop` command only increases the stack pointer, does not change the value on the stack.
* A `push` command often modifies the stack, unless it's possible to prove that the stack value is always equal to the pushed value.
  That includes `push lr`.
 
So, to loop we should:
 
* When `sp = A`, and a `pop pc` command is executed, execute something that may modifies the stack.
* Return the stack to the original value.
* Execute a gadget with `pop er14; pop pc` and put `A-2` on the top of the stack.
* Execute a gadget with `mov sp, er14; pop er14; pop pc`.
 
 
Typically the stack is returned to the original value by calling the null-terminated string copy function on a 100-byte region that is not modified before the used stack content. As it's quite hard to determine which region is "not modified", this is often done by trial and error.
 
-------
 
### Example
 
### TODO
 
--------
 
### TODO: Is there any unclear part (that you can't understand)?
 

Edited by user202729, 28 February 2018 - 12:27 PM.


#324 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 23 February 2018 - 05:05 PM

@user202729: Thank you, it's pretty clear, I suggest adding some examples (directly in your post) and explaining how they work (which addresses do they jump to, etc).



#325 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 24 February 2018 - 01:25 PM

 

### TODO: Should I do Hello World first? Is this one overkill?

### TODO: Is there any unclear part (that you can't understand)?

 

I'm afraid this is a bit overkill for me (for example, "About why we uses `0:3441` and not `0:343e`, read the section about `lr` above." is quite unclear and I think that actually mentioning the code that gets executed, at least the important parts, would significantly help).

 

Yes, I think a simple, but well-explained Hello World would be better.



#326 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 24 February 2018 - 05:06 PM

Instead, we jump to the command **right after** the `push lr`. That way the `pop pc` will pop the top of the stack at that time, and we can control the value of `pc`.

 

So we have to jump to the second instruction of a function to make sure we can force it to return the PC to the address we need when it exits, correct?



#327 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 27 February 2018 - 04:12 PM

Updated Javascript code: (replace the one inside #301)

https://github.com/u...i-translator.js

NOTE. This may be made deprecated in the future.

Edited by user202729, 14 June 2018 - 03:28 PM.


#328 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 27 February 2018 - 04:23 PM

Code for scrolling text:
 

Memory structure:
| z = 94
| d = 162
| d1 = 163
| e = 194
[B1 ------ code ----------- | ----- data -----] (333)       [--- B2 ---] (356)     [--- B3 --- | --- data ---] (359)
(z)                        (d) (d1)           (e)           (z)                               (d)

============

explanation | keypresses
------------+------------
wait        | A F 0 -
------------+------------
pop xr0     | cv24 M 1 -
b1.e<-b3.d  | cv08 pi cv16 Ran#
copy        | (-) cs23 0 -
------------+------------
pop xr0     | cv24 M 1 -
b1.d<-b1.d1 | Permu pi Combi pi
copy        | (-) cs23 0 -
------------+------------
pop xr0     | cv24 M 1 -
b1.d,1 line | Permu pi mp -
disp        | A 4 0 -
------------+------------
pop xr0     | cv24 M 1 -
b1.e<-b1.z  | cv08 pi cs29 pi
restore stk | (-) cs23 0 -
------------+------------
actual EP   |
(#52 char)  |
------------+------------
pop er14    | Int / 0 -
b2.z-2      | x10 Ans
jump        | log / 0 -
------------+------------
data part   | <32 bytes>
------------+------------
logical EP  |
------------+------------
pop er0     | sin 2 0 -
wait time   | 0 0

(note: The `0 0` at the end corresponds to `3030` in hexadecimal (the former `0` corresponds to the latter `30` because of little-endianness) = 12336 in decimal, so each "tick" takes 1.2336 seconds)


Edited by user202729, 28 February 2018 - 04:02 PM.


#329 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 27 February 2018 - 08:02 PM

Demo video: https://www.youtube....h?v=wTOBvgXfnB4.



#330 SopaXorzTaker

SopaXorzTaker

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 155 posts
  • Gender:Male
  • Interests:Electronics and programming.

  • Calculators:
    fx-991ES PLUS

Posted 28 February 2018 - 12:36 PM

KEAr5vv.png

 

Font (for reference)



#331 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 27 May 2018 - 01:20 PM

[Data loader for 570ES+]

This will load the data on the screen. The # address to write to part need to be changed.

There are no way to break the loop except by overwriting the loop itself.

The whole program only take 90 bytes. Carefully golfed. However the input format is very weird.

Tested on the emulator.
 
start:
	getkeycode
	er8 = er0
	getkeycode
	r2 = r0
	r0 = r8, pop r8
	0x3333 # not important, for r8
	set lr
	er0 += er2
	r2 = r0    # now r2 holds the bytevalue

	# store that bytevalue to (*y)
	pop er0
y: # address to write to
	0xf830
	[er0] = r2

	# increment (y)
	er2 = 0x0101
	call 0x1852c # those 3 lines set er2 to 1
	er8 = adr_of [-200] y
	[er8] += er2, pop xr8
	0x33333333 # not important

	# restore the stack
	xr0 = adr_of [-117] start, adr_of [-217] start
	strcpy

home:
	goto start
Passing the code above through https://github.com/u...ter/compiler.py to get the hexadecimal format

3130e23d3030a032303030f86a273030b244303001012c8531306c743030868b0a44303033333333ee543130b38b4f8b602730306a4f3030268c684f30303334353637383930313260b430308c46313060b43030e23d3030b02c30303333631e3130ec6c
and keypress list
 
1 0 cv12 = 0 0 sin( 2 0 0 0 cv34 ∫( cs23 0 0 tan⁻( D 0 0 cs1 cs1 , ° 1 0 Pol( ×⏨ 0 0 ʳ Ans cs10 D 0 0 3 3 3 3 cv24 M 1 0 Rnd( Ans ÷ Ans - cs23 0 0 ∫( ÷ 0 0 cs22 Ran# log( ÷ 0 0 3 4 5 6 7 8 9 0 1 2 - cs30 0 0 Ran# F 1 0 - cs30 0 0 cv12 = 0 0 sin⁻( , 0 0 3 3 Abs( cs17 1 0 cv22 Pol(
-----------

In order to quickly test this on the emulator, you can append https://github.com/u.../lua_helper.lua to the model.lua file, then type
 
inject '3130e2<...>'
to the Lua prompt (replace the <...> part with the actual code) and then press [=] on the emulator.

Edited by user202729, 07 October 2018 - 08:12 AM.


#332 frankmar98

frankmar98

    Casio Freak

  • Moderator
  • PipPipPipPip
  • 127 posts
  • Gender:Male
  • Location:Spain
  • Interests:Science, programming

  • Calculators:
    CFX-9970G
    Graph 90+E (fx-GC50)
    fx-9860G SD
    Classpad 300
    HP Prime
    TI-84+ CE-T
    x2 TI-83+
    TI-81
    fx-4800p, fx-3650PII
    fx-991SPX, fx-991ES PLUS, fx-100W

Posted 01 June 2018 - 06:40 PM

This is very interesting, I'm taking my time to read and understand your work, and I expect to try it in my units. 

 

Is it safe for the calculator?

 

 

I have splitted this message from your thread, because it is other model, probably you will want to answer it:

http://community.cas...ge-1#entry61757

 

Thanks!



#333 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 05 June 2018 - 12:21 PM

For the ES PLUS calculator series:

Very safe.

A hard reset (enter the diagnostic mode and exit it) should fix everything.

#334 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 06 June 2018 - 04:30 AM

(reply to CalculatorDestroyet)

For calculators without Sigma or Calc (e.g., fx-82ES PLUS, fx-83GT PLUS):

#220 contains a method to get in STAT 0-submode.
Also described in a post in 1.3.4 below.

#218 contains a link to http://tieba.baidu.com/p/3395822027 . Section 1.3 contains some useful links.

Quoting the Google-translated version here:
 

1.3, Casio fx-82ES PLUS (fx-350ES PLUS) abnormal application of
...... 1.3.1, abnormal application of finishing paste: http://tieba.baidu.com/p/1800667172
...... 1.3.2, overflow in linear mode: http://tieba.baidu.com/p/2741812956
...... 1.3.3 Absolutely anomalous layer theory and some layers measured: http://tieba.baidu.com/p/3071775731
...... 1.3.4, bid farewell to the RP era - the new version into the 68 mode method: http://tieba.baidu.com/p/3061327586
...... 1.3.5 Overclocking Scheme: http://tieba.baidu.com/p/2334872700
...... 1.3.6. Single line spelling: http://tieba.baidu.com/p/2806987125
...... 1.3.7, dynamic garbled: http://tieba.baidu.com/p/3325006253
...... 1.3.8, garbled new discovery: http://tieba.baidu.com/p/3347248899


Although that's for 82ES and 350ES, most methods there can also be applied here. In particular:

68 mode (memory retention mode)
Basic overflow
(this creates a box, which can be used to enter more than 99 characters in the input, hence "basic overflow")
Abnormal STAT mode (submode 0).

All of those methods are not completely "deterministic", and require some timing to get right.
"Abnormal STAT mode" is the easiest one to get right.

-----------

Unfortunately I can't find any 83GT-specific information. There is this topic but it does not mention about hacking.
Looks like that you have to try it yourself. At least I have the emulator. (although the emulator's behavior is not exactly the same as the real calculator, only "reasonably similar"

Edited by user202729, 07 June 2018 - 04:12 PM.


#335 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 07 June 2018 - 04:18 PM

If anyone interested, I made a wiki at http://casiocalc.wikidot.com .
(because the previous wiki site made by nm111 is non-editable)

Anyone can help by copy and paste information in this topic to the wiki. (with appropriate formatting and organization)
I may need to fix later.
(I'm not familiar with wikidot, so if you can't create account etc. tell me)

#336 amn

amn

    Newbie

  • Members
  • Pip
  • 7 posts

Posted 07 June 2018 - 09:01 PM

If anyone interested, I made a wiki at http://casiocalc.wikidot.com

 

I'm interested but for whatever reason I only see the page: "Become a Member" although I'm logged in to wikidot.



#337 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 17 June 2018 - 04:22 PM

Fn _strcpy_nn, adr 4e50
Fn _strcat_nn, adr 96ea
Fn _memcpy_nn, adr 7ef6
Fn _memmove_nn, adr 4ce8
Fn _strlen_n, adr 8b82
Fn _memset_n, adr 7e94
Fn _strchr_n, adr 8ba0

7 functions found. Of course for other calculator models the addresses would be different.

Generating code in my github repo named fxesplus,
file wine_tools/parse_all_obj.py.
Before that run wine_tools/extract.py
(remember to configure the path to LIB file)
to generare the .obj files.

Edited by user202729, 21 June 2018 - 09:47 AM.

  • amn likes this

#338 space928

space928

    Newbie

  • Members
  • Pip
  • 4 posts
  • Gender:Male
  • Location:France/Switzerland
  • Interests:Computing
    Science
    Programming (C, C#, HLSL, and rarely ASM)
    Theatre
    Maths

  • Calculators:
    fx83-gt PLUS
    And occasionally: fx92 Spéciale College

Posted 12 August 2018 - 06:38 PM

Hi, I've been loosely following this topic for a while now and have decided to join in. I have an fx-83GT PLUS, which I know is a bit behind the 991es PLUS as far as overflow bugs go but I have had mild success with mode 68 (I've got it twice so far but it's really hard to get). I can get the empty box but I can still only type 98 characters, is there something that I'm doing wrong?

 

I've been looking at the test pads on the back of my calculator (PCB photo below) and I have found a few interesting things. I've found the pads for all the buttons as KI/KO pads which I could hook into an arduino to experiment with triggering mode 68 and other things related to the corrupted STAT mode. There are other pins as well though that I might try and probe with the arduino though I doubt it will be able to poll fast enough and I don't own an oscilloscope.

 

I'm going to keep looking into using the arduino to control the calculator but I don't really have the right equipment and I don't want to solder onto my calculator, but if someone could point me towards a good emulator I could use to poke at that would be good, otherwise I don't know what is really yet to be explored with this.

 

Here's a summary of what I found about the board:

P = test pad, goes from Switch --> Pad --> CPU
Buttons, pulled high-ish (like 200k resistance between vcc and pad) when off and low when on

P132=ON Button
P164=GND
P167=VCC
P155-159=Go to the CPU only?
P0-1=Correspond to KI/KO???
P150-151=KI4-KI5
P104-107=Power
P132-136=Button to CPU???
P146=CPU?
P101=No solar panel

//See the key table for KI/KO:
KI n
KO n

Board Photos:

https://photos.app.g...KsqtAN1t9cUPrU6

https://photos.app.g...eTVhYUU98RFsK5A



#339 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 13 August 2018 - 07:58 AM

Emulator.

Either use CASIO's official emulator -- it's quite different from the real calculator,
in particular, most bugs that corrupts the stack fails to execute.
Or LBPHacker's emulator -- you need to dump the ROM from the calculator.
There is no fixed way to do this, as return-oriented programming requires knowledge about exact addresses of code inside
memory, and that is different for each memory model.

---

68 mode and empty box.

With an empty box on fx-ESPLUS calculator model, it should be possible to enter basic overflow with an empty box.
Then it's possible to enter more than 100 characters.
I just tried doing this on the emulator (approximately, by hacking memory mode) and it works.
Note that the box should not be "overwritten" in the process.

---

Corrupted STAT mode is easier to get than 68 mode, however it's less obvious how to work with the r
(currently it's just "enter a random formula, press [=], hope that the stack is correct")

#340 space928

space928

    Newbie

  • Members
  • Pip
  • 4 posts
  • Gender:Male
  • Location:France/Switzerland
  • Interests:Computing
    Science
    Programming (C, C#, HLSL, and rarely ASM)
    Theatre
    Maths

  • Calculators:
    fx83-gt PLUS
    And occasionally: fx92 Spéciale College

Posted 13 August 2018 - 09:06 AM

Ah, I figured out what I was doing wrong with the basic overflow, I forgot to move the cursor into the empty box so it just got overwritten when I tried to type into it. I'll experiment with some hackstrings once I get mode 28 again and I'll look for LBPHacker's emulator. I might keep poking at some of the test pads though, I'm curious about the ones I said went straight to the CPU (at least by the looks of the traces they did), I'll try and probe them.



#341 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 19 September 2018 - 06:17 AM

I decide to try to reverse-engineer the emulator to see if I can get anything useful.
Enabling log on the emulator produces the code block below.
I don't know if it's the same as the real calculator, but if the code for interacting with interrupt table
is the same on the real calculator, it's likely. 
 
 Memory Model: LARGE
 Result:
 Code Range: 0 - 2ffff
 CMem Start: 0  End: ffff
 GMem Start: 0  End: 1ffff
 Result:
 Data Range: 8000 - 8ffff
 DMem Start: 8000  End: ffff
 GMem Start: 0  End: 7ffff
 Result:
 RomWindow Range: 0 - 7fff
 Interrupt Table:
 01. Vector: 0008  IE: 0000.0  IRQ: f014.0  Name: WDTINT
 02. Vector: 000a  IE: f010.1  IRQ: f014.1  Name: XI0INT
 03. Vector: 000c  IE: f010.2  IRQ: f014.2  Name: XI1INT
 04. Vector: 000e  IE: f010.3  IRQ: f014.3  Name: XI2INT
 05. Vector: 0010  IE: f010.4  IRQ: f014.4  Name: XI3INT
 06. Vector: 0012  IE: f010.5  IRQ: f014.5  Name: TM0INT
 07. Vector: 0014  IE: f010.6  IRQ: f014.6  Name: L256SINT
 08. Vector: 0016  IE: f010.7  IRQ: f014.7  Name: L1024SINT
 09. Vector: 0018  IE: f011.0  IRQ: f015.0  Name: L4096SINT
 10. Vector: 001a  IE: f011.1  IRQ: f015.1  Name: L16384SINT
 11. Vector: 001c  IE: f011.2  IRQ: f015.2  Name: SIO0INT
 12. Vector: 001e  IE: f011.3  IRQ: f015.3  Name: I2C0INT
 13. Vector: 0020  IE: f011.4  IRQ: f015.4  Name: I2C1INT

Edited by user202729, 19 September 2018 - 06:22 AM.


#342 sleirsgoevy

sleirsgoevy

    Newbie

  • Members
  • Pip
  • 11 posts

  • Calculators:
    fx-991es plus
    cfx-9950gb plus

Posted 04 October 2018 - 08:22 PM

It seems that Neg( in the data loader must be changed to Abs(, since Neg( is impossible to type in COMP mode. Changing Neg( (0x62) to Abs( (0x63) will have no effect since the CPU ignores the last bit.

By the way, I've tested the loader on a real fx-991es. It seems to work, however some keys produce different symbols than in COMP mode.


Edited by sleirsgoevy, 05 October 2018 - 06:01 PM.


#343 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 07 October 2018 - 05:48 AM

@sleirsgoevy: You're right about that, Abs( | 0x63 is better than Neg( | 0x62. Updated.
However: It is possible to enter Neg( and other symbosl in the COMP mode using the "unstable character"
(the timer of the calculator, used as a random source)
See http://casiocalc.wik...ter-unsupported .

Edited by user202729, 07 October 2018 - 02:03 PM.


#344 sleirsgoevy

sleirsgoevy

    Newbie

  • Members
  • Pip
  • 11 posts

  • Calculators:
    fx-991es plus
    cfx-9950gb plus

Posted 24 October 2018 - 03:25 PM

I've modified user202729's compiler so that it's able to produce output that's to be loaded by the data loader.

https://drive.google...K3HgwFdmfh_JD15



#345 siealex

siealex

    Casio Addict

  • Members
  • PipPipPip
  • 70 posts
  • Gender:Male

  • Calculators:
    570w, 570ms, 83es, 570es, 83gt plus, 991es plus, 991de plus, 570spx ii, 9750gii

Posted 27 October 2018 - 08:07 PM

I'm completely new here (I bought a 991DE Plus two days ago :D). Two questions...

1. Do these 991ES Plus hackstrings work on 991DE Plus? I can't get any of them working, my device only freezes or performs a factory reset.

2. What is Mode 68 and is it possible on 991DE Plus?



#346 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 29 October 2018 - 03:59 PM

1. Do these 991ES Plus hackstrings work on 991DE Plus? I can't get any of them working, my device only freezes or performs a factory reset.


The methods that keeps the calculator in working state (does not corrupt the stack) should work.
Executing hackstrings will definitely not work.

2. What is Mode 68 and is it possible on 991DE Plus?


See http://casiocalc.wikidot.com/mode-68.
(currently the wiki is poorly maintained/organized. I only add information when somebody asks or I remember that I should add something)

#347 siealex

siealex

    Casio Addict

  • Members
  • PipPipPip
  • 70 posts
  • Gender:Male

  • Calculators:
    570w, 570ms, 83es, 570es, 83gt plus, 991es plus, 991de plus, 570spx ii, 9750gii

Posted 09 November 2018 - 09:34 PM

 

 

See http://casiocalc.wikidot.com/mode-68

 

How to get "r" inside the square root sign? Or must it be outside?



#348 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 10 November 2018 - 09:55 AM

How to get "r" inside the square root sign? Or must it be outside?


Use [INS] button (SHIFT, DEL).

This is supposed to be basic knowledge, because it's listed in the calculator manual...

#349 TheAwesomer

TheAwesomer

    Newbie

  • Members
  • Pip
  • 24 posts

Posted 06 December 2018 - 07:26 PM

Hi, after lurking around for a while I decided to make an account. I too am very interested in this. I have a fx-85ES (not plus) and also managed to get the fx82ES emulator. If you need me to try anything in Cheat Engine, feel free to tell me.

 

Some odd things I have found:

 

Interestingly enough, typing 'r' for f(X)= when in table mode will go alright until the table is attempted to be made, at which point the calculator will
just simply hang instead of shutting off like it does when you type 'r' on its own anywhere else. I did this on the emulator, but when you do r on its own normally the screen glitches for a second (in emulator it just stays glitched) where as in this scenario it just straight up hangs but nothing other than that.
 
Even more odd though, if you have 1:r instead, nothing atall seems to happen out of the ordinary!


#350 TheAwesomer

TheAwesomer

    Newbie

  • Members
  • Pip
  • 24 posts

Posted 06 December 2018 - 07:33 PM

Also couldn't you possibly scratch at some of the pcb traces on a Model B fx-82ES and upgrade it to a fx-991ES that way?



#351 TheAwesomer

TheAwesomer

    Newbie

  • Members
  • Pip
  • 24 posts

Posted 06 December 2018 - 07:56 PM

Another thing I found in the emulator code:

 

https://i.imgur.com/FmqoGAa.png



#352 siealex

siealex

    Casio Addict

  • Members
  • PipPipPip
  • 70 posts
  • Gender:Male

  • Calculators:
    570w, 570ms, 83es, 570es, 83gt plus, 991es plus, 991de plus, 570spx ii, 9750gii

Posted 18 December 2018 - 06:36 PM

 

 

Use [INS] button (SHIFT, DEL).

I've already found it, but this formula does not work on 991DE Plus...



#353 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 19 December 2018 - 04:03 PM

Uh, of course. I wrote there that that one is for only those specific models.

#354 TheAwesomer

TheAwesomer

    Newbie

  • Members
  • Pip
  • 24 posts

Posted 02 January 2019 - 01:03 PM

UPDATE: I found a casio fx-82ES on EBay that wasn't advertised as being a model A (or even a model B for that matter) but looked suspiciously like it was a model A (the back picture was low quality) and bought it. When I got it, it was in better condition than I first thought and it actually was a model A. Purchased it for just £8.00 too! Then ofcourse I went ahead and opened it up and used a little metal nail file to split the solder on the mode pad in half so that I could then bridge a different mode pad instead and got it to MODE P4! So that was a success.

 

As for the emulator I have found, using some special programs, the fx-82es emulator is showing up as being Microsoft Visual C++ 6.0

Going to try to decompile it using this information.

 

Will update you on whether or not I am successful.

 

 

UPDATE2: Well, I guess I was kind of successful... I managed to decompile section 0 of the emulator (i didnt try other sections though) but I can't actually save or copy the result because its too big and attempting to select it all just hangs the program before you can even copy to clipboard (and there's no save function, annoyingly.). But maybe this means it is somewhat possible, because I did actually get a result (a big one at that, and that's only section 0). Of course there is plenty of margin for error in the decompiled code, but it might give us an insight into the program at the very least. In case you are interested, the emulator is coded in Visual C++ 6.0 (I did a hardcore scan with PEiD to find this out) and I decompiled with Snowman (to find just search "derevenets" on google). I tried it with Boomerang first but it just crashes upon trying to even load the file so that's a no-go.


Edited by TheAwesomer, 02 January 2019 - 02:13 PM.


#355 sleirsgoevy

sleirsgoevy

    Newbie

  • Members
  • Pip
  • 11 posts

  • Calculators:
    fx-991es plus
    cfx-9950gb plus

Posted 03 January 2019 - 07:00 PM

I've discovered some interesting thing about the calculator's memory layout.

Firstly, 15 bytes at 0x860e-0x861c always contain bytes 0x0f-0x01. That's probably a magic number to verify the RAM integrity, however, putting those at the correct positions inside the hackstring is not enough to fool the calculator.

Secondly, the 'getkeycode' routine (f_0B45E) actually blinks a character, not just a pre-defined image. The character code is stored at 0x08116, and offset from the left side of the screen (in pixels) is stored at 0x8114.



#356 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 04 January 2019 - 10:23 AM

I tried decompiling the emulator of fx-es plus calculators once. There isn't anything
very interesting.

Regarding "RAM integrity", the calculator verifies various things on startup (for fx-ES
PLUS calculator); if any of them fail then the calculator will be resetted:
(the function is at address 045A6 on fx-570ES PLUS)

* The magic string (start at 0x860e) is 0x0f .. 0x01.
* The contrast (at 0x810E) is no larger than 0x1d and no smaller than 0x04.
(basic overflow don't affect this)
* None of the 10 variables (M, Ans, A, B, C, D, E, F, X, Y) has an invalid value.
Variable M is at 0x8226, Ans is at 0x8226+0xA, ...
The checking code looks like this (where er0 points to the variable, which is 10
bytes long):
 
f_1B4EA:
	l r2, [er0]                    ; 1B4EA | 9200
	and r2, 15                     ; 1B4EC | 220F
	cmp r2, 10                     ; 1B4EE | 720A
	bc ge, .l_014                  ; 1B4F0 | C006
	l r2, 9[er0]                   ; 1B4F2 | 9208 0009
	and r2, 240                    ; 1B4F6 | 22F0
	bc ne, .l_014                  ; 1B4F8 | C802
	mov r0, 0                      ; 1B4FA | 0000
	rt                             ; 1B4FC | FE1F
.l_014:
	mov r0, 1                      ; 1B4FE | 0001
	rt                             ; 1B500 | FE1F
I thought about having the calculator not reset after performing a hack, but I find
invoking the reset-all routine for that purpose easier.

----------

Regarding the calculator's memory layout: some info is known for me (for example the
cursor X position is at 0x8114), but not all.

Edited by user202729, 04 January 2019 - 10:25 AM.


#357 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 07 January 2019 - 03:43 PM

Interesting observation:

The function at 195bc starts with push lr and ends with rt.
Fortunately the caller happens to have just the correct code for it to work fine.

This can either be because of
  • My program made an error while reading the ROM from the calculator LCD.
    In that case it must be very lucky for the checksum to match.
  • The developer intentionally put an easter egg.
  • Some bit-flip error happened while compiling the ROM.
  • Compiler bug.
  • The compiler intentionally generate this for some reason. As far as I can see, this does not
    reduce code size or number of executions executed, so this is unlikely.
By the way, I implemented the ability to print stack trace in my fork of the emulator.
I noticed this while running sin(1).

Edited by user202729, 09 January 2019 - 05:27 AM.


#358 sleirsgoevy

sleirsgoevy

    Newbie

  • Members
  • Pip
  • 11 posts

  • Calculators:
    fx-991es plus
    cfx-9950gb plus

Posted 12 January 2019 - 05:14 PM

By the way, I've managed to raise the program size limit to about 2 kilobytes, by loading a modified copy of the data loader and then loading the program itself with that. (I've successfully loaded a ~300 bytes program).

Modified loader and compiler are here: https://drive.google...iew?usp=sharing

EDIT: While the theoretical limit is 2 kilobytes (2118 bytes), getkeycode seems to erase bytes in range(0x87d0, 0x87dc), so this hole will need to be jumped over to write larger programs.


Edited by sleirsgoevy, 14 January 2019 - 07:51 PM.


#359 dung11112003

dung11112003

    Newbie

  • Members
  • Pip
  • 3 posts

  • Calculators:
    fx-570ES PLUS
    fx-570VN PLUS
    fx-580VN X

Posted 13 January 2019 - 06:17 AM

Hello,

I'm new to this hacking method. I have read some tutorial on this topic, but i can't understand how to dump ROM.

Could anyone explain me how to do that?



#360 anon34

anon34

    Casio Freak

  • Members
  • PipPipPipPip
  • 268 posts

Posted 14 January 2019 - 09:20 AM

See https://community.ca...ge-8#entry61348 .

Then capture a video of the screen, process it to get the ROM.


2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users