News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Valendian

Pages: [1] 2
Programming / Re: Hacking the Linux Kernel?
« on: September 24, 2018, 06:39:49 pm »
What's wrong with pure C? No other language could replace it. You would have to outpace a planet full of engineers all churning out C. Think you can do better? Head on over to osdev and give it a shot. I did

Newcomer's Board / Re: I need help finding a ROM hacking tool...
« on: August 21, 2018, 03:06:35 am »
Sorry if I came off as rude. I don't doubt your ability or appetite. But there are no tools for what you want to do and thats a big blocker. Before investing the time in that, it may be worthwhile learning on a game that already has this support. It will pay off in the long run

Newcomer's Board / Re: I need help finding a ROM hacking tool...
« on: August 20, 2018, 05:02:47 pm »
You gotta start somewhere. But your first game the best advice is:

Start with a simple 8bit game
Start with a game that has all the tools you need

If there are no tools then you need to make them, or you will need to apply generic tools and some simple scripts.

Programming / Re: How to use syscall/ disc read in psx assembly?
« on: August 10, 2018, 04:10:38 pm »
You may have better luck tracking the data tables that store the LBA of the file data. That way your files will be treated just like the normal files. You can find these tables by placing breakpoints on CDROM DMA, then back trace the stack to find the original call point.

If this is not possible then you need to read the manual. This documentation is a great place to start:

A-Functions (Call 00A0h with function number in R9 Register)

A(A5h) - CdReadSector(count,sector,buffer)
Reads <count> sectors, starting at <sector>, and writes data to <buffer>. The read is done in mode=80h (double speed, 800h-bytes per sector). The function waits until all sectors are transferred, and does then return the number of sectors (ie. count), or -1 in case of error.

A(A6h) - CdGetStatus()
Retrieves the cdrom status via CdAsyncGetStatus(dst) (see there for details; especially for cautions on door-open flag). The function waits until the event indicates completion, and does then return the status byte (or -1 in case of error).

ROM Hacking Discussion / Re: [PSX] How to find a graphic in memory?
« on: July 16, 2018, 02:22:33 pm »
Texture and sprite data must be DMA transferred to VRAM. Polygons must be drawn. The pSX emulator has a debug menu which allows you to debug gpu commands. You can capture a number of frames and it will allow you to step through the rendering of each frame one polygon at a time. For each polygon you can see which function issued the draw command.

Yeah its always going to be tedious when you work so close to the metal. But every small step is progress and all adds up over time.

These values you're looking for, do you know roughly where the data lives? If you have some idea then corrupting that region of data will help narrow it down. This is much faster than walking through code.

Or do you know the function in which it should be accessed? Only thing to do here is set a break point at the function entry point, when that triggers the debugger will break. Take this opportunity to make a save state so you can rewind the clock. Nop out instructions and step through over and over again, that's all you can really do here.

Static analysis (reading the code) is difficult, it is better to use a debugger. The debugger will allow you to watch the code execute in slow motion so you can observe how the data flows through the registers. A debugger does this by allowing you to step through the code one instruction at a time and will pause until you manually step forward. Break points can save time. If you place a read/write break point on data, then the debugger will run like a normal emulator but will stop when the game reads or writes that data. You can also place execute break points on instructions.

ROM Hacking Discussion / Re: Help With ASM!
« on: May 01, 2018, 09:36:04 am »
Im not sure i fully understand the problem. But i can clarify at least one area of confusion. You are changing bytes and this effects the disassembly. There are two possible causes
1) the bytes are program instructions and by changing those bytes you are corrupting the program.
2) the bytes are data and just so happen to map to well formed instructions. This is possible and requires you to use reasoning to determine it is data.

Are there invalid instructions mixed in to this area of the program? If so then most likely it is data and the dissasembly has no meaningful information.
Otherwise the changes to the disassembly are purely because you changed the bytes. In this case you can assume that those bytes are part of the program and the data is elsewhere

Programming / Re: I like ASM... What's similar?
« on: April 29, 2018, 10:06:49 am »
Check out this guys channel it is great for showcasing the technology behind old school games.

He targets those videos for complete begginers and its not asm but c++. But it will introduce you to c++ while having fun

Following pointers is a difficult task. It requires a lot of detective work. I find that you can use the stack as a cookie trail. If the pointers are read in one place then used in another, then there is likely to be a function call where the pointer is passed as an argument. Break on memory read/write to the data and save state. Then search the save state for the pointer. You are hoping to see a few occurrences near each other. This area is the stack (and is typically found at top of memory 801Fxxxx).
The stack grows down so the occurence with the highest address is the place where the pointer was read. Break on write to that address and you are within the function that reads the pointer. Locate the start of this function and step through it until the pointer is read. Its a lot of work following pointers but it pays off.

ROM Hacking Discussion / Re: PSX - Relocating pointer table
« on: February 27, 2018, 05:01:45 pm »
Im not the biggest fan of that mnemonic format but what is this doing?
Code: [Select]
800164bc 00621821: ADDU    801a6d3c (v1), 801a6d3c (v1), 000003f8 (v0)
There is no opcode for 32bit indexing. Is there any chance that this is a pseudo opcode? If so the pointer will appear split up like this

Code: [Select]
lui v0, 0x801b
ori v0, 0x6d3c

You're using a std::vector<char> for the sliding window, I think this is creating a new problem rather than solving an existing one. The problem is made more simple by using a fixed sized c-style char array all you need to do is use modulus wrap around to enforce boundary constraints. Also the negative start index in the Sliding Window is dubious, I'm not sure if this is because you are using a vector but I really would consider dropping the std::vector and switching to a fixed sized c-style char array.

Code: [Select]
    // using a std::vector is creating more problems than it solves
    realOffset = ((offset + i) > 0xFFF ? (offset + i) - 0x1000 : offset + i);
    buf.push_back(buf[sldWindow->getStart() + realOffset]);

Code: [Select]
    // if you use a char[] it would look more like this
    buf[end++ % sizeof(buf)] = buf[(offset + i) % sizeof(buf)];

And this appears to be LZSS. The distinguishing feature of this LZ variant is that it maintains a separate sliding window. It treats the sliding window as a FIFO queue. Earlier variants simply took the position in the output stream and grabbed bytes from earlier positions, (the sliding window was a subset of the output stream and would contain duplicate entries).

Also when you get around to encoding you will need to layer some other technique on top to get satisfactory results, the basic example I pointed to earlier doesn't do anything fancy and so its compression ratio is rather poor. Huffman Coding can be used to improve this ratio.

ROM Hacking Discussion / Re: ROM Hacks to Disable Dithering in PS1 Games
« on: February 21, 2018, 10:18:03 pm »
You need to modify the GPU Rendering Attributes which is command GPU0(E1).

Search for the following memory mapped IO address 0x1F801810 it will probably appear similar to the following
Code: [Select]
  lui     r4, 0x1F80     #
  lw      r3, 0x1810(r4) #

modify the code so bit 9 is cleared
forgot to add that you need to find the references that write 0xE1xxxxxx to that port address (E1 command).

you can zero init the buffer with char buf[BUFFER_SIZE]={0};

Not when the array is used more than once.

@730 if those errors only show up at the end then all you are missing is the end of file logic.

EI is the bitsize of the pointer and EJ is the same for copy size. N an F convert these to buffer size and lookahead size. The lookahead is ised during compression to find longer duplicates within the sliding window. P is also only used during compression. It is the minimum string length, less than this will be stored raw.

The decoder works like this.
Read a bit.
If its 1 then the next bytes are raw. so read 8 bit count and copy that many raw bytes from the packed input to the output. Every raw byte is also appended to the sliding window (buffer).

But if the bit was clear then read a pointer + size pair and copy from the window instead.

Your version is not bit packing so replace getbit with readbyte.

Note LZSS uses sliding windows. LZ just offsets from current output pointer. Watch that slight difference. As Gemeni noted all LZ decoders have a similar form. The different versions are just tweaks.

it keeps getting shifted right by 1 bit every loop that a byte is stored to the decompressed area (also at some point it gets 0xFF added to it, such that it ends up being 0xFFXX, XX being the loaded byte, and I think this loaded byte is also the bytes that are "skipped" that I mentioned).

I think you found the getbits function. The typical LZ type decoder has three paths:
  1  Uncompressed raw data
  2  Compressed pointer / size pair
  3  End of file marker (-1 in the code below)
Although any attempt to compress such a small payload will result in expansion. I think this is a more of a text preprocessor than any form of depacker or decrypter.

Anyways here's what an LZ decoder looks like
Code: [Select]
// source
unsigned int   insize;
unsigned int   outsize;
unsigned char *indata;
unsigned char *outdata;
unsigned int  inptr;
unsigned int  buf;
unsigned int  mask = 0;
unsigned char buffer[N * 2];

// get n bits
int getbit(int n) {
    int i, x;
    x = 0;
    for (i = 0; i < n; i++) {
        if (mask == 0) {
            if ( inptr >= insize ) return -1;
            buf = indata[ inptr++ ];
            mask = 128;
        x <<= 1;
        if (buf & mask) x++;
        mask >>= 1;
    return x;

void decode(void) {
    int i, j, k, r, c;
    for (i = 0; i < N - F; i++) buffer[i] = B; // clear the buffer to avoid infinite loops
    r = N - F;
    while ((c = getbit(1)) != -1) {
        if (c) {
            if ((c = getbit(8)) == -1) break;
            out[outsize++] = c;
            buffer[r++] = c;
            r &= (N - 1);
        } else {
            if ((i = getbit(EI)) == -1) break;
            if ((j = getbit(EJ)) == -1) break;
            for (k = 0; k <= j + 1; k++) {
                c = buffer[(i + k) & (N - 1)];
                outdata[ outsize++ ] = c;
                buffer[r++] = c;
                r &= (N - 1);

The bottom one is not compressed, "Ten emos que subdir". pSX can break on CDROM DMA, if you do not know the DMA address then set the range to all memory 80000000-801FFFFF

The PS1 memory addresses usually end in 0x80

Just to expand this a little:
pointers which refer to cached memory are in the 2 MB range:
    0x80000000 (00 00 00 80) - 0x801FFFFF (FF FF 1F 80)
Tune you eye to see 80 in the third column of a 4 byte word, it's and important signature for a pointer.

The MIPS CPU strictly enforces alignment of data. The instruction set requires that 4 bytes words lie on a 4 byte boundary, likewise for halfs (2 bytes). However small data like a byte may just happen to be 4 byte aligned. You can use a debugger to verify the size of data once you know where it lives in RAM. Place a Break-Point on read/write. You will see one of the following assembly instructions:
  4 byte word ... LW/SW (load/store)
  2 byte half ... LH/LHU/SH
  1 byte ... LB/SB
(Just be mindful that memory transfers will use word copies for byte arrays).

If you are using a debugger then the bytes are right their ready to be fuzzed, you can save/reload state and the turn around time is instant. You can lean on the hex editor for searching the save state. There is a fixed difference between the save state offset and RAM address, for pSX at least (doesn't compress the save states).

Nice choice to take on Tekken 3.Shows good taste. I did notice that those data structures have a variable length string of text. This usually means that the name is the last thing in the structure you already noticed those names are zero filled to a four byte alignment. Nulls like these are used to mark the end of text. Now you have a note that indicates that the structure begins four bytes later.I would question that.
Not sure if it helps but have you tried to count up all the names and search for that number. You will likely find a descriptor in the header.

Keep fuzzing those bytes

ROM Hacking Discussion / Re: How to use pSX emulator with hardware logging?
« on: February 02, 2018, 01:16:12 pm »
You need to go use the Front End or else it doesn't capture things correctly.
When you have the logging window open the log will display all bios calls and parameters. However you will need to learn how to read each log entry as the information is there but can be tricky to extract the information.

Pages: [1] 2