• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

ASM Tutorials

Blah

Free supporter
1,924
Posts
11
Years

ASM Tutorials!


Hello, around these parts I go by the name of "FBI Agent", though everyone calls me FBI. I've been doing ASM for about 4-ish months now and I think I've become adept enough at it to teach it to others. Hence I've made some tutorials of many many different difficulties which I hope you can both understand, enjoy and learn from :)


Tutorials:


Inserting ASM (ASM Skill 0/10)
You should need to learn how to insert ASM before attempting to really do it. Very basic skill and useful outside of these tutorials as well.
link: http://www.pokecommunity.com/showpost.php?p=8526603&postcount=199

Beginner's guide (ASM Skill 1/10)
It's a basic tutorial on how to do some simple pointer reading and writing. Expects you to know how to insert ASM and some exposure
to concepts like "What is a stack" and "What is a pointer". You should also be adept at hex editing/scripting.
link: http://www.pokecommunity.com/showpost.php?p=8625298&postcount=10

Beginner's guide (ASM Skill 3.5/10)
It covers some nice nooks and crannies about the basics. It's got a few "higher level" concepts in there, but I think you can handle that.
Expects completion of the first beginner's guide. A good "tips and tricks" guide if you ask me.
link: http://www.pokecommunity.com/showpost.php?p=8625292&postcount=8

Intermediate guide (ASM Skill 5/10)
Finally introduces a debugger and teaches you how to use one. Get comfortable with it, because it's going to be with you the rest of the way!
Expects completion of all beginner's guides and perhaps some experience writing beginner ASM as well as exposure to a debugger.
link: http://www.pokecommunity.com/showpost.php?p=8625280&postcount=7

Intermediate guide (ASM Skill 6.5/10)
Teaches core concepts needed to become adept at ASM hacking. Including indepth looks at how to hook from routines, overwriting functions, use of functions
editing functions. Expects completion of intermediate tutorial (1).
link: http://www.pokecommunity.com/showpost.php?p=8616786&postcount=5

Expert guide (Need a good topic first...)

Links to some tutorials others have written that you should check out:
(in order of difficulty, in my opinion)
link : http://www.pokecommunity.com/showthread.php?t=233645
link : http://www.pokecommunity.com/showthread.php?t=117917
link : http://www.pokecommunity.com/showthread.php?t=233661

I haven't linked Jpan's tutorial because his tutorial is more of a documentation. I suggest you read it, its good for reference and even I use it sometimes.

If you have questions regarding ASM in general and not about this tutorial:
Please visit the ASM help thread in the beginner's lounge. If it's a question, please DON'T PM me. My box is almost always full these days and I don't like PMs.
If it's a question regarding something specific to the guide (perhaps something not explained well enough or something you don't understand in the context, feel free to ask).
 
Last edited:

kearnseyboy6

Aussie's Toughest Mudder
300
Posts
15
Years
  • Seen Jun 22, 2019
Very good tutorial, this explains how to actually find a routine in the ROM which is something I lacked.

One thing I'm unsure about is how you derived what was inside the stack pointer. Is this a much more complicated concept? Because a lot of the tutorial was based off tracking the SP.
 

Blah

Free supporter
1,924
Posts
11
Years
Very good tutorial, this explains how to actually find a routine in the ROM which is something I lacked.

One thing I'm unsure about is how you derived what was inside the stack pointer. Is this a much more complicated concept? Because a lot of the tutorial was based off tracking the SP.

You're right, I kinda just gave it away. Basically I found out when doing the translation of Raw code into pseudo code.
The start of the code area we were examining was something like this:

Code:
ROM:08011366 loc_8011366:                            
ROM:08011366                                         
ROM:08011366                 MOVS    R6, #0
ROM:08011368                 LDR     R0, =0x823EAC8
ROM:0801136A                 LDR     R2, [SP,#0x20]
ROM:0801136C                 LDR     R3, [SP,#0x14]

You'll notice in my pseudo code part, I said
Code:
r6 = 0
r0 = start of table
r2 = 0x1D0 @This is Flag ID * 4
r3 = 0x74 @JANICE's flag ID

When you're converting Raw code into pseudo code, you need a little more information for the things to make sense. I (at the time) didn't know what was in r0, r2, or r3 so I opened VBA-SDL-H, set a break point to this code and pressed "n" (next instruction) until the values were loaded into them. From there I noticed that the flag ID was written into r3, and later on to r1 in the same way, via SP. This meant that at some point down the road, the game must've written to SP the trainer ID.
(Actually if you're smart about it, trainer battles are always called via scripts, and in scripts you need to specify a trainer ID in the paramaters. From there you can guess that the trainer ID isn't derived, it's actually just directly written into RAM :D ).

I didn't include this info in the tutorial because I thought that the conversion process between ASM -> Pseudo might be a little hard for some people. After some experience you can generally just look at something and pretty quickly see what's going on. Anyways, for the next tutorial on hooks and stuff, I'll definitely include more information about how one would go about converting ASM to pseudo code. It's generally just a line by line analysis until you kinda see the "big picture".

Thanks for the feed back, and hopefully that answered your question.

Although I doubt to have many questions from people, remember if you have questions regarding the tutorial it's alright to ask here (like Kearnseyboy6) but if you have questions about ASM in general it's probably best to ask in the help thread.

Also if you're working on something ASM and want more "quick" help, feel free to join our super elitist chat room. Where daniilS will tell you your code sucks, and then kick you from the room. http://chat.linkandzelda.com:9090/?channels=GoGo

Finally, after my hooking tutorial (which will be rather soon, hopefully) feel free to propose more ideas about what the next tutorial should be on. I'm kinda trying to do new material no one's covered before, but obviously having trouble coming up with ideas. I'm also thinking of making a more basic one for earlier concepts like handling pointers, writing data to RAM, ect in ASM. Tell me whatchya think.
 

Blah

Free supporter
1,924
Posts
11
Years

"Hooking" from existing routines


Hooking is a term Touched used to refer inserting your own branch from an existing routine to your routine. I'm not sure if the term has got other significant meanings in the programming world, but that's where I heard it from. Anyways this word has sort of grown on me, and I find myself using it to describe the aforementioned situation. Anyways, like the previous tutorial, this one requires for you to have already gotten the basics down. The difficulty will be around the same as the last tutorial, it should be much shorter, though I'll be introducing a few new concepts.

For this guide you will need:
- IDA 6.5 & Knizz's Database or the VBA emulator
- Hex Editor (just to search for hex strings)
- VBA-SDL-H or similar Disassembler (btw VBA-SDL-H is linked in HackMew's tutorial. I don't have permission to use his link, so go and get it there)


Tutorial goal:
As you may know, there's a limit on how long item names can be. An item is only allowed to be 14 characters, actually if you consider the 0xFF string terminator, this 14 becomes 13 usable characters. So our goal is to figure out a way to remove this limit and have the string be any length.


Developing an algorithm

Spoiler:


Finding where to hook from


Spoiler:


Studying our Hook location

Spoiler:


Doing the hook


Spoiler:


Writing the ASM


Spoiler:


Challenges and some info


Alrighty, it's time for the next challenge :D

Can you make it so Pokemon Names can be greater than 13 characters? We need a Fakemon named Mega SuperDuperCharizardous!

The other thing I wanted to say in this section, was that if you have any questions regarding my tutorials specifically, or suggestions, please ask. If you have general ASM questions please ask them in the appropriate threads. While I don't particularly mind answering them here, I'm sure the staff and people browsing in the future would appreciate if everything was nicely sorted. Also if you have questions regarding ASM and no one seems to be online/helping or if you just want to chat, head over to our iirc at channel #GoGo. Yeah...GoGo named the channel after himself :P
 
10,078
Posts
15
Years
  • Age 32
  • UK
  • Seen Oct 17, 2023
Thanks for the tutorials FBI. I've been avoiding ASM for a long time - I did the beginner tutorials but everything got left so up in the air I hadn't really learnt much anyway. Now there's more tutorials seems like a good time to start learning some simple ASM :).
 

Blah

Free supporter
1,924
Posts
11
Years

Practical ASM Guide for those past the beginner guides


Note this is not a tutorial for commands, or specifics of technicalities. In this guide I will only explain the process one would apply to accomplish ASM feats. If there is need to explain technical aspects to understand the material, I'll explain myself. Otherwise it's expected you know simple things like what some commands are doing, concepts understanding of Pointers, RAM and other stuff like that.


Introduction


I've recently decided to write a guide/tutorial kinda thing on some ASM writing/research process. I should warn the reader that this guide requires some prior knowledge of ASM. If you haven't already I suggest you read HackMew's part 1 tutorial, JPAN's tutorial document on thumb, and ShinyQuagsire's guide to ASM. Once you've become comfortable at writing your own routines(at a basic level), understanding this guide would be the next step on your adventure to conquering the ASM world.

Anyways to complete this guide you'll want to get your hands on:

- legal copy of IDA 6.5
- knizz's data base
- some debugging tool (it just needs to have a search function for current RAM and ability to set break points. I'm going to be using VBA-SDL-H).

To some degree you can substitute IDA for Visual Boy Advance's dissembler (but it's just not nearly as good). I won't be linking any of those things here because I'm a little lazy to find the links. But I will be using VBA's disassembler here instead of IDA, because I know a lot of people won't be able to get their hands on a copy. Though if I ever do make further guides, or if you plan on writing some more difficult ASM, you NEED IDA. It's a pretty big advantage.


Introducing the goal/task


Spoiler:


Confirming suspicions

Spoiler:


Conducting the investigations


Spoiler:


Finding Where something is defined


Spoiler:


The ray of hope


Spoiler:


Back tracking, for science!


Spoiler:


Writing ASM code for our findings



Most of the work is the research. Writing the code itself is generally easy, especially if you know what you're doing.

Spoiler:


Ending notes:


I hope you noticed that we can do simple tweaks to this routine to make it output something else that's in the trainer table. In fact, if you ever need to display some text from a table, this is the structure
that you would need to apply. The only thing that would change is the 0x28 (which was the space between entries in the table) and the start of the table (in this case the trainer table was 0x20386AE).

So here's a challenge for you (yes I'm shamelessly copying HackMew and ShinyQuagsire's idea of having a little challenge at the end), make a routine to buffer the Trainer's class. I.e Lass, Camper...ect.


For next time:
Hooks from existing functions!
 

Blah

Free supporter
1,924
Posts
11
Years

Basic tips and tricks when ASM hacking


I decided to do a little bit of a tutorial-kinda write up of a few tricks and tips which I use when I'm writing routines. I hope to go over some of the more less known uses for some OP codes as well as how to work with pointers, tables and similar stuff in an ASM context. I should warn you that this tutorial assumes you already have atleast a vague idea of what OP codes do. I'm not going to be explaining technically what they do, unless of course its needed to understand the context. In general I assume you already know what some commands are doing.


Deriving larger constants into a register


There are a lot of times where you need to assign a value to a register. I'll give you an example. Say in my routine I wanted to do something if flag 0x828 (the Pokemon menu) flag was set. Well, before I can check that flag I first need to set a register to 0x828, obviously. But how can one go about doing that? First try on your own to make a routine which sets register zero to 0x828. Once you have a working solution look at mine in the spoiler below. I encourage you to first make your own solution. Push all the registers you need in your routine as well. For now, don't worry about the .txt .align and that stuff at the top and bottom, just write the body.

Spoiler:



Working with tables and pointers


Tables are the main (actually probably the only) way which the game organises it's data. Tables can be seen when dealing with moves, abilities, Pokemon, names, sprites, functions, and a lot of other things. When you're writing ASM routines, it's often the case that you will need to read through a table.
Or if you're writing ASM routines, sometimes you may want to allow others to easily custimize it by reading things from a table. In this section I will be explaining how you would go about processing a table in ASM.

There are in general two types of tables in the game. The first type of table is terminated by a terminating byte or entry. The second type doesn't have any termination indicators, but is expected to have a fixed length. Sadly the second type of table is mainly from poor design, but we still have to deal with it. Moving on, both types of table have all their data formatted in equal lengths. Take the move name table for example. Moves like "Haze" obviously have shorter names than moves like "Perish song", however in the table they always take the same amount of space. This is because every table has "padding" which are basically 99% of the time "00" bytes which act as a filler between the first index and the second index of the table. You might wonder why I'm explaining how tables work in an ASM tutorial, but I think it's important to clear
any misunderstandings before proceeding to the ASM.

To write ASM for browsing through a table we need:
1) The amount of bytes each entry in the table takes up (they are all the same because of the padding I talked about)
2) The address to the first entry of the table (well we need to know where the table is)

Lets try writing some ASM to do things with some existing tables.

Developing the routine:
We're going to work with the move names table.
1) Each name is 13 bytes long and ends with 0xFF as a terminator
2) The table does not have a terminating byte
3) The table starts at 0x8247094

The task:
Don't worry about the stuff at the start or end of the routine (the .align 2, .thumb ect. Just write the body). Load into r0 the address of the 20th move (i.e the move in the 13th index). Try it before looking at my solution.

Hints:
- In this case it's easier to use mul than lsl. So use mul.
- Use ldr r0, =(0x8247094) to load the table's pointer

Bonus: Can you load the first letter of the move?
Spoiler:


That's how you would read from a table if you knew which index you wanted. What if you were searching for something in a table?
Lets say that you had a table of item IDs which in your Hack were considered "sellable". Now lets say you have an Item with ID 0x55. How would you know the item is sellable given the table? You would have to search every index in the table until you reach the end, OR find byte 0x55. Lets try seeing if 0x55 in in a table which terminates with 0xFFFF (that means the end of the table, is signified by 0xFFFF btw). Notice that I said the terminator was 0xFFFF. That's because item IDs are halfwords, so the terminating "byte" is actually 2 bytes. Try it yourself and then look at my solution. Once again, you just include the main body for now.

1) Pretend table starts at 0x740000
2) Pretend each item ID is a half word (2 bytes)
Hint: Instead of ldrb use ldrh to load a half word.
Bonus: Set r0 to 0x0 if we find 0x55. If we don't find it set r0 to 0x1

Solution:
Spoiler:



Using functions in the game


Before I explain to you how to use a function, I should first explain to you what a function is like. Basically it's a bit of code which performs a series of operations based on 0 or more parameters it's given. An example of a function would be the "checkflag" command we know from scripting. This command, is parsed from your script by the scripting engine into ASM.

Code:
checkflag 0x828
So checkflag is actually a function with takes a flag number as it's paramater. It returns in Lastresult the status of that flag, 0x0 for unset and
obvously, 0x1 for set. Like that there are functions in ASM. Obviously in ASM they are much more "raw" then our friendly scripting languages.

The check flag function in ASM is located at 0x806E6D0. It takes a flag number in r0, and after execution, it returns in r0, 0x0 for unset and 0x1 if set.
This happens to also be the function your scripting command "checkflag" is calling in the end after its done parsing your parameters.

Lets try using it to see if flag 0x828 is set.

Code:
main:
	push {r0-r2, lr}
@derive 0x828 in register r0
	mov r0, #0xFF
	lsl r0, r0, #0x3
	add r0, r0, #0x30
@this is how we call the function
	ldr r1, =(0x806E6D0 +1)
	bl linker
@check if set or not
	cmp r0, #0x1
	beq set
	pop {r0-r2, pc}

set:
	@if we get here it's set

linker:
	bx r1

Take a moment to understand what I've done here. Basically, we know that the function takes in r0 a flag number for a parameter. So we made r0 to be 0x828. We can called the function using a free register and bl linker (I will talk about that soon). After that, the function puts in r0 the state of the flag. We then checked if the flag was set, if it was goto set, else just end the routine.

As promised I'll talk briefly about
Code:
	@stuff here
	ldr r1, =(0x806E6D0 +1)
	bl linker
	@Proceed to do stuff here

linker:
	bx r1

As you should know, "bl" is a the branch with link command. It basically jumps to some point in the ROM and writes to the link register the address of the next instruction. Then when the function it jumped to is done and does "pop {pc}" or returns some other way, it will return back to whichever address was written into the link register. Unfortunately the "bl" command is limited. You compiler will not let you compile this due to the reason that "bl" might not be able to reach the function. So instead we use "bx", which jumps to a function and has unlimited range. However, unlike "bl", the "bx" command doesn't write to the link register. So we find this clever way of combining the two commands to jumped
to a function AND return, when normally we couldn't. So in this example, after the flag checking function finishes doing it's stuff, the code will jump back to the part where I'm written "@Proceeds to do stuff". It's fine if you don't understand this part, as it requires some understanding of how the link register works and a few technical details on the instruction set, all you really need to take away is how we do it. But if you want to be a good ASM hacker, definitely take the time to understand what's going on here.


Manipulating registers even more


Hmm, this topic is a little more advance, but I think at this level it can be handled quite well. Basically I'll be talking about how to use lsl and lsr to remove "garbage" data from registers as well as how to concatenate values in registers. I'm going to start it off with a practical example. As you may know, each Pokemon in FireRed is unique even among the same species. This is caused because most of the Pokemon's base values are determined by a random value the Pokemon is assigned called the Pokemon ID, or PID for short.

The PID is formed by combining two pseudo-random numbers the game created. The way they are combined aren't mathamatical, but rather by concatenation.
Here's what I mean:
X = a random 4 byte number
Y = a random 4 byte number (different from X)

PID = [First 2 bytes of X][Last 2 bytes of Y]

so if X = 0xDE6C3B8F and Y = 0xCA9B23E1
then PID = [DE6C][23E1], which says PID = 0xDE6C23E1.

But how would you go about doing this? We would need to remove the last 2 bytes of X and the first 2 bytes of Y. Then we would need to combine them. Luckily, we know a few commands which can remove some bytes. They are lsl and lsr. While lsl and lsr work on a bit level, if we shift off enough bits it would be the same as shifting off bytes. Recall that a register has 4 bytes of data. We want to shift off 2 bytes worth. 2 bytes is the same as 16 bits. 16 in hex is 0x10. So lsl r0, r0, #0x10 would shift off the first 2 bytes. But then we'd end up with something like "XXXX0000" because our last 2 bytes were shifted up. So we need to shift back right by 0x10 to give us "0000XXXX". With this new knowledge in mind, try and write a routine to do this!

Assume:
1) r0 and r1 contain two different random values (so don't push)
2) we want the first half of r0 and the last half of r1
3) Put the result in r0 (bonus I don't expect you to do)

Hint: Think of which direction you need to shift to get the first half or the second half. Remember to restore them back

Solution: Before looking, try steps 1 to 2.
Spoiler:


The shifting is very straight forward, so I won't be explaining that. Reread the other sections if you don't understand.
I'll explain the "orr". The best way to look at orr is to look at two arguments it would take side by side and see what it's going. Take:
X = XXXX0000
Y = 0000YYYY

If I did "orr r0, x, y", then I'm putting into r0 whatever the result of orr x, y is. orr combines the two values in a strange way which is useful. It basically takes the first argument (X in this case) and substituted any "0x0" digits in X with the corresponding digits in Y. So this would become "XXXXYYYY". Once you see how it works, it becomes kinda of obvious how it's doing what it is. If you've studied logic gates, this is the same as logical OR. Similarly there's an "and" and "xor operation too. You can read about their functionality online, as it would end up being a tutorial on what the OP codes are if I did so myself.


End:


I think that once you've mastered this tutorial, you're probably well on your way to trying the intermediate ones. Before you go though, here's a nice little challenge.

Random move buffer!:

The scripting command "random" sets variable 0x800D to a random value between 0x0 and 0xFF. We will consider this value to be a random move ID. In the same script you will need to use the callasm command to go to your routine's address (don't forget to add 1). From there, make a routine which reads the value in variable 0x800D. Navigate the move table to the index specified by random and, copy the corresponding move name into the RAM location 0x2021D18.

Required info:
1) The move table starts at 0x8247094
2) Each index in the move table contains a move name
3) Each index in the move table is 13 bytes long (0xD in hex)
4) Each move name is 0xFF terminated to signify the end of the name
5) The RAM address of 0x800D is 0x20370D0

Your script should look like this:
Spoiler:


Hints:
There is a function which copies an 0xFF terminated string from 1 address to another. It can be used to copy the string in the table into 0x2021D18! This function is at 0x8008D84. Good luck! (Also with the knowledge from this tutorial, you can make your own string copy if you want. It's possible).
 

Blah

Free supporter
1,924
Posts
11
Years

ASM Guide for the Noobs


Most of my ASM tutorials have been pretty difficult in comparison to what's already been published on the tutorials section regarding the topic.
So I've decided to make a rather simple tutorial, just covering super basically what you need to know before kick starting into your journey!

Prerequisites: Try out HackMew and ShinyQuagsire's ASM tutorials. Also know how to compile and insert ASM. Look at the first post for these links.

Commonly used thumb commands


Here's a breif look at some common commands to refresh your mind. For concepts like "what is a stack" I expect you to read the tutorials I've
mentioned in the prerequisites section. Examples are separated by ";". Also some of these commands have signed versions, but I will not be
addressing those here. It requires some knowledge of technical implementation, and beginners don't need to know that just yet.

Spoiler:



The task!


Recall that the script command "random" sets variable 0x800D to a random number between 0x0 and 0xFF. Imagine that you're writing a script which
takes a random value via the random command and adds it to variable 0x8000. How would you do this in a script? The answer is we can't. Ultimately,
we need a way to do "addvar 0x8000 0x800D" which adds the values of the two variables together and perhaps puts the result in 0x800D.
Sadly, this scripting command doesn't exist. The only way to achieve such a mathamatical operation is to use ASM. Which is where we come in!!!
Expanding the game while adding useful features is something you can do with ASM. I decided to make this specific tutorial on adding variables
because I think it's practical and you can use it for other purposes outside of this tutorial.

Make sure you have a compiler and notepad handy, we're going to write some code!


Writing the routine


So lets start making our routine. The first thing we need is the routine's frame.
Spoiler:



Testing the routine


Well, I know it works because I made it, but it's possible you might want to test this routine out. This routine was made for the purpose of
performing operations inside scripts (it can work outside scripts as well, but that's for another tutorial), so we can use the "callasm" command to test.

Anyways, compile the routine we made and insert it into your ROM. If you don't know how. Refer to the first post.
Try this script ingame and see if it works! Remember to update that "callasm" line according to what I've written there.
Code:
#dyn 0x740000
#org @start
'---------------------------------------------
'recall random stores it's result in 0x800D
'storevar is buffernumber in XSE
'---------------------------------------------
lock
faceplayer
random 0xFF
setvar 0x8000 0x34
storevar 0x1 0x8000
storevar 0x0 0x800D
msgbox @watchMeAdd
callstd MSG_NORMAL
callasm 0xWhere you inserted your routine + 1
storevar 0x0 0x800D
msgbox @result
callstd MSG_NORMAL
release
end

#org @watchMeAdd
= I'm smart I can add uhhh[.]\n\v\h02 and \v\h03! Give me a sec!

#org @result
= It's \v\h02! Ha I told you!
That's all for this tutorial!
 
Last edited:

Blah

Free supporter
1,924
Posts
11
Years
Thanks for the tutorials FBI. I've been avoiding ASM for a long time - I did the beginner tutorials but everything got left so up in the air I hadn't really learnt much anyway. Now there's more tutorials seems like a good time to start learning some simple ASM :).

No problem I enjoy writing them, and it helps clear my understand of what I know when I try to put it into text. So it's a good opportunity.

Uhh...sorry Mod's for the quadruple post. I posted 2 new guides, Updated the first post and decided to reply to Magic for the 4th post :3
 
3,044
Posts
9
Years
No problem I enjoy writing them, and it helps clear my understand of what I know when I try to put it into text. So it's a good opportunity.

Uhh...sorry Mod's for the quadruple post. I posted 2 new guides, Updated the first post and decided to reply to Magic for the 4th post :3

Hm, I might try the guides. I would like to know how to make an ASM routine. Thanks!
 
5,256
Posts
16
Years
I'm curious as to why you do all this complicated math to pass larger constants into registers.

Is there something wrong with this method?

Code:
	mov r1, #0x82 @r1 = 0x82
	lsl r1, r1, #0x4 @r1 = 0x82 * 0x10 = 0x820
	add r1, #0x8 @r1 = 0x820 + 0x8 = 0x828

That way, knowing which values you have to use can be derived from mere inspection (i.e. divide by ten, then see what the remainder is).

Loving these tutorials either way, they're very useful!
 

Blah

Free supporter
1,924
Posts
11
Years
I'm curious as to why you do all this complicated math to pass larger constants into registers.

Is there something wrong with this method?

Code:
	mov r1, #0x82 @r1 = 0x82
	lsl r1, r1, #0x4 @r1 = 0x82 * 0x10 = 0x820
	add r1, #0x8 @r1 = 0x820 + 0x8 = 0x828

That way, knowing which values you have to use can be derived from mere inspection (i.e. divide by ten, then see what the remainder is).

Loving these tutorials either way, they're very useful!

The method you've shown in the code section is the method I have recommended at the end :o

In practice it can be better to do ldr r0, =(large constant). Or something like ldr r0, largeConstantSymbol. Especially if the constant is needed to be derived multiple times.

There ARE going to be times when you can't use the ldr r0, =(large constant) method, an example would be in a loop if we're taking a value in r2 and then multiplying it to find an index in the table. The table index might have an offset of "0x8723234" but given for formulaic nature of the loop we NEED to use math to derive it rather than ldr. So overall I say learn how to do it using lsl and lsr as mathamatical operators, while keeping ldr in your back pocket.

If you look at some of my routines I use lsl/lsr to derive values, and I use ldr to load offsets. It keeps things neat and understandable, I find.
 

DriveTG

Retarded's Hunter
25
Posts
9
Years
Thanks to this type of contributions the best advances RH. With ASM are God in your very own hack. :D
 
15
Posts
9
Years
  • Age 22
  • Seen Oct 22, 2021
Umm.. I wrote ASM to load the move name, but this code makes the game freeze. But I don't know what is wrong with this.
Spoiler:
Any solution?
 

Blah

Free supporter
1,924
Posts
11
Years
Umm.. I wrote ASM to load the move name, but this code makes the game freeze. But I don't know what is wrong with this.
Spoiler:
Any solution?

Code:
@Call Function
	ldr r1, =(0x08008D84 +1)
	bl linker
Remember that this function, string copy, takes an 0xFF terminated string's pointer in R1 and a destination to put it in R0. Here you have the source in R0 (while it should be in R1) and you haven't specified where to store the string. If you read the tutorial again, you'll notice I give a RAM location which is suitable for the string's destination. Load that RAM location into R0 and keep the move's ROM location in r1. Try it out.

Navigate the move table to the index specified by random and, copy the corresponding move name into the RAM location 0x2021D18.

Solution (just the part that was wrong):
Spoiler:
 
Last edited:

jiangzhengwenjzw

now working on katam
181
Posts
11
Years
  • Seen today
Hello? This tutorial is nice. I have gone through your tutorial "Intermediate guide (ASM Skill 5/10)" and I have tested it but I do not know much about the ram offset "02021D18". You said that it's "the RAM location for displayed strings in textboxes for scripted messages", so why it's safe? When will it be overwritten?
 

Turtl3Skulll

Blue Turtl3
76
Posts
10
Years
FBI, you will just never disappoint me! This tutorial is incredible, even after going through all the other ASM tutorials, I only got the basics of how to use the commands, but you definitely know how to teach this, only read 1/2 but LOVE this tut!!! Keep up your Freaking amazing work bro!! :D
 

Touched

Resident ASMAGICIAN
625
Posts
9
Years
  • Age 122
  • Seen Feb 1, 2018
These are really good FBI. It's nice to see some of the actual techniques publicly available here. FYI, hooking is an actual programming term, not just something I use. It would be nice if you did some IDA tutorials so people can become wizards actually learn to hack.
 
Back
Top