Register

Addin manager: need to manipulate RAM & SMEM

Discuss issues related to Calculator Hacking/Modding.
Junior Member
Posts: 9
Joined: Sun Aug 21, 2016 10:33 am
Calculators: None

Addin manager: need to manipulate RAM & SMEM

Postby Zezombye » Tue Jan 03, 2017 5:37 pm

Hi,

I am planning to release an addin manager. Features will be :
- Shuffle addins
- Change addin icon, name, version, and appname

For shuffling addins, according to https://bible.planet-casio.com/simlo/ch ... cy_RAM.HTM the addin array is at 0x88006D9C. Theoretically all I would have to do is some memcpy. However, is the ram location the same with every OS? If not, is there a reliable way to know the location of the addin array (some syscall)?

For changing the addin icon, name, version and appname (name = displayed name in the system app, appname = beginning with an '@' and used for folders) I would have to write and read at the specific offset (for example: addin appname is at offset 0x20, so I would only modify the 8 bytes at 0x20, without loading the whole addin into ram). The Bfile_ReadFile and Bfile_WriteFile sdk functions seem to do what I want, but is the pointer in the addin array the same pointer that is expected by these functions (the "HANDLE")?

Also, does the appname spans 8 or 9 bytes (including the '@', excluding the '\0')?

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Addin manager: need to manipulate RAM & SMEM

Postby SimonLothar » Wed Jan 04, 2017 6:41 am

Zezombye wrote:For shuffling addins, according to https://bible.planet-casio.com/simlo/ch ... cy_RAM.HTM the addin array is at 0x88006D9C. Theoretically all I would have to do is some memcpy. However, is the ram location the same with every OS? If not, is there a reliable way to know the location of the addin array (some syscall)?
The start address of the addin array is OS dependent, indeed. You can use the following code to retrieve it. I am not sure, whether it is possible to shuffle the addin array elements. The system registers the available addins every now and then, building the addin array anew.
The syscall:
0x000E: int App_GetAddinEstripInformation( int addinno, int estripno, TAddinEstripInformation*result );
code: Show
Code: Select all
typedef struct{
  char name[8];
  void*address;
} TAddinArrayItem;

typedef struct {
   short p1;                                          // 0
   short estrip_no;                                    // 2
   TAddinArrayItem*addin_array_addr;            // 4
   void*estrip_location;                              // 8
   void*addin_smem_location;                     // C
   void*estrip_icon_location;                        // 10
} TAddinEstripInformation;

// ************************************************
int F07_1_Handler(){
unsigned int key;
unsigned char s[22];
short*p;

TAddinEstripInformation aei;
   App_GetAddinEstripInfo( 0, 0, &aei );

   Bdisp_AllClr_VRAM();
   
   locate( 1, 1 );   
   IntToHex( (int)aei.addin_array_addr, s );
   Print( s );
   GetKey( &key );
   
   return 1;
}
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Addin manager: need to manipulate RAM & SMEM

Postby SimonLothar » Wed Jan 04, 2017 6:46 am

Zezombye wrote:Also, does the appname spans 8 or 9 bytes (including the '@', excluding the '\0')?
8 bytes. Also refer to http://casiopeia.net/forum/viewtopic.php?f=21&t=1774
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Addin manager: need to manipulate RAM & SMEM

Postby SimonLothar » Wed Jan 04, 2017 7:34 am

Zezombye wrote:For changing the addin icon, name, version and appname (name = displayed name in the system app, appname = beginning with an '@' and used for folders) I would have to write and read at the specific offset (for example: addin appname is at offset 0x20, so I would only modify the 8 bytes at 0x20, without loading the whole addin into ram). The Bfile_ReadFile and Bfile_WriteFile sdk functions seem to do what I want, but is the pointer in the addin array the same pointer that is expected by these functions (the "HANDLE")?
It is not possible to overwrite existing data with Bfile_WriteFile, if 0->1 bit transitions are involved. You have to create a file of a fitting size and copy the changed data. In case of an addin, this file must not be the running addin, because the addin is executed directly from SMEM.
I'll be back!

Junior Member
Posts: 9
Joined: Sun Aug 21, 2016 10:33 am
Calculators: None

Re: Addin manager: need to manipulate RAM & SMEM

Postby Zezombye » Wed Jan 04, 2017 7:37 am

That's all I needed to know - thanks!

Another thing I'd like to do is change the OS icons, and perhaps other things like character bitmaps, main menu banner or extinction screen. Would it be possible securely (don't want to brick any calc)?
The way I'd do it is:

Code: Select all
char bitmap[] = {...}
int bitmapSize = //size in bytes
int i;
for (i = OS_START; i <= OS_START + OS_SIZE - bitmapSize; i++) {
   int regionMatchesBitmap = TRUE;
   for (int j = 0; j < bitmapSize; j++) {
      if (bitmap[j] != *((*int)i)) {
         regionMatchesBitmap = FALSE;
         break;
      }      
   }
   if (regionMatchesBitmap) break;
}
//i is now the location of the bitmap in the OS


Basically iterate over the OS to see if a region matches the bitmap.
However how would I know the OS start and size?

Junior Member
Posts: 9
Joined: Sun Aug 21, 2016 10:33 am
Calculators: None

Re: Addin manager: need to manipulate RAM & SMEM

Postby Zezombye » Wed Jan 04, 2017 6:19 pm

After some testing I've encountered a problem with the storage memory.
I manage to get the addin array start and print the name of the addin (from the addin array). However:

- Going to the pointer (addin_start + 8) seems to be 2 addins over (if I try to locate the first addin and read its name, it instead reads the name of the 3rd addin). Trying to access the pointer of another addin yields a system error (for example, if I do addin_start - 4 or + 20). I don't know why it behaves like that :o However the syscall GetAddinHeaderAddr seems to work.

- I can't write in the RAM at all, it seems. Trying to modify the name of an addin, internal name (in the addin array) or swapping their position doesn't do anything. Do addins not have write access to RAM/SMEM by absolute adresses? How would I bypass this?

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Addin manager: need to manipulate RAM & SMEM

Postby SimonLothar » Wed Jan 04, 2017 8:02 pm

It would be best to post the part of the source, which probably malfunctions.
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Addin manager: need to manipulate RAM & SMEM

Postby SimonLothar » Wed Jan 04, 2017 10:41 pm

Zezombye wrote:Another thing I'd like to do is change the OS icons, and perhaps other things like character bitmaps, main menu banner or extinction screen. Would it be possible securely (don't want to brick any calc)?
The menu-icon of an addin is stored in the G1A-file. The other icons are stored inside the OS. So if you want to change them, you'd have to change the OS.
I'll be back!

Junior Member
Posts: 9
Joined: Sun Aug 21, 2016 10:33 am
Calculators: None

Re: Addin manager: need to manipulate RAM & SMEM

Postby Zezombye » Thu Jan 05, 2017 7:04 pm

Here is the complete code:
Code: Show
main.c:
Code: Select all
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#include "fxlib.h"
#include "main.h"

unsigned int key;
int i;
int* addinArray = NULL;

typedef struct{
  char name[8];
  void*address;
} TAddinArrayItem;

typedef struct {
   short p1;                                          // 0
   short estrip_no;                                    // 2
   TAddinArrayItem*addin_array_start;            // 4
   void*estrip_location;                              // 8
   void*addin_smem_location;                     // C
   void*estrip_icon_location;                        // 10
} AddinEstripInfo;

int AddIn_main(int isAppli, unsigned short OptionNum) {
   //Various strings for testing
   char s[9] = "TESTABCD";
   char s2[9] = "TESTABCE";
   char s3[20] = {0};
   char s4[9]= "AddInMGR";
   char placeholder[12];
   unsigned short path[] = {'\\','\\','f','l','s','0','\\','G','E','O','M','E','T','R','Y','.','G','1','A'};
   int handle = 0xC0FFEE;
   int* ptr;
   
   //Get addin array start; seems to work, although on OS 1.3 (SDK OS) it is 0x88006DA0 not 0x88006D9C
   AddinEstripInfo aei;
   getAddinEstripInfo(0, 0, &aei);
   addinArray = aei.addin_array_start;
   
   //Print the name of the first addin using the addin array; works
   locate(1,1);
   memcpy(s, addinArray, 8);
   Print(s);
   intToHex((int)addinArray, s3, 8);
   locate(1,4); Print(s3);
   
   //Get pointer to first addin address
   //Note that setting handle to (int)(addinArray+8) gives the pointer to the 3rd addin address!
   //Trying to access a pointer to another addin (addinArray+20 or addinArray-4) gives a system error.
   //However this syscall gives the correct pointer.
   getAddinAddress(0,0,&handle);
   if (!handle) Print(" error");
   intToHex(handle, s3, 8);
   locate(1,5); Print(s3);
   
   //The handle Bfile_OpenFile returns is not the same as the pointer,
   //so the addin address doesn't work for Bfile_Read/WriteFile.
   //intToHex(Bfile_OpenFile(path, _OPENMODE_READ), s3, 8);
   //locate(1,6); Print(s3);
   memcpy(s2, (int*)(handle+0x20), 8);
   //s2[0] = Bfile_ReadFile(handle, s2, 8, 0x1D4)+'A';
   locate(1,2); Print(s2);
   
   //Try to copy content of s4 into name of addin; doesn't work, gives the correct pointer and does nothing
   ptr = memcpy((int*)(handle+0x1D4), s4, 8);
   if (ptr == NULL) {
      locate(1,7); Print("null ptr");
   }
   intToHex((int)ptr, s3, 8);
   locate(1,6); Print(s3);
   
   //Read name of addin; is still the same as before
   memcpy(s2, (int*)(handle+0x1D4), 8);
   locate(1,8); Print(s2);
   
   //Now, try to swap the 1st and 2nd addin positions in the RAM; doesn't work
   memcpy(addinArray, s4, 8);
   memcpy(placeholder, addinArray, 12);
   memcpy(addinArray, addinArray+12, 12);
   memcpy(addinArray+12, placeholder, 12);
   do {
      GetKey(&key);
   } while (key != KEY_CTRL_EXE && key != KEY_CTRL_AC);
   return 1;
}

#pragma section _BR_Size
unsigned long BR_Size;
#pragma section

#pragma section _TOP
int InitializeSystem(int isAppli, unsigned short OptionNum) {
   return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}
#pragma section

syscalls.src
Code: Select all
   .export   _getAddinEstripInfo
   .export   _getAddinAddress
   .export _intToHex

_getAddinEstripInfo:
   mov.l   syscall_table, r2
   mov.l   _getAddinEstripInfo_code, r0
   jmp   @r2
   nop
_getAddinEstripInfo_code:
   .data.l   H'00E

_getAddinAddress:
   mov.l   syscall_table, r2
   mov.l   _getAddinAddress_code, r0
   jmp   @r2
   nop
_getAddinAddress_code:
   .data.l   H'00A
   
_intToHex:
   mov.l   syscall_table, r2
   mov.l   _intToHex_code, r0
   jmp   @r2
   nop
_intToHex_code:
   .data.l   H'467

syscall_table:
   .data.l   H'80010070

   .end


The menu-icon of an addin is stored in the G1A-file. The other icons are stored inside the OS. So if you want to change them, you'd have to change the OS.

I know, but is there a way to overwrite the OS? I could do that securely by iterating over the OS until I match a bitmap (I could match some code that happens to match the bitmap, but is it unlikely?), however how would I know the start and size of the OS? Do I need to recalculate checksums?

If I manage to overwrite the OS I will probably also add support to change other things (extinction image, menu banner, character bitmaps, language strings...)

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Addin manager: need to manipulate RAM & SMEM

Postby SimonLothar » Thu Jan 05, 2017 10:27 pm

Zezombye wrote:Here is the complete code:...
You declared addinArray as int*. A pointer is incremented by the size of the type it points to. addinArray+12 would increment the pointer by 12 int-sizes, t. i. 48. I think (char*)addinArray+12 should work. Or (TAddinArrayItem*)addinArray+1.
I'll be back!

Next

Return to Calculator Hacking/Modding Discussions

Who is online

Users browsing this forum: No registered users and 26 guests