Can you write to [PC]? - dcpu-16

According to the DCPU specification, the only time a SET instruction fails is if the a value is a literal.
So would the following work?
SET [PC],0x1000
A more useful version would be setting an offset of PC, so a rather strange infinite loop would be:
SET [PC+0x2],0x89C3 ; = SUB PC,0x2

Probably (= I think it should work but I didn't try).
This is called "self modifying" code and was quite common the 8bit era because of a) limited RAM and b) limited code size. Code like that is very powerful but error prone. If your code base grows, this can quickly become a maintenance nightmare.
Famous use cases:
Windows 95 used code like this to build graphics rendering code on the stack.
Viruses and trojans use this as an attack vector (write code on the stack or manipulate return addresses to simluate a JMP)
Simulate switch statements on the C64

There's no value for [PC], so I'm guessing you need to do it in a round-about way by storing PC in something you can use as a pointer (registry or memory).
SET A , PC
SET [A+3], 0x8dc3 ; SUB PC, 3 (if A can't be changed from outside SUB PC,2 works too.)

Related

How to tell compiler to pad a specific amount of bytes on every C function?

I'm trying to practice some live instrumentation and I saw there was a linker option -call-nop=prefix-nop, but it has some restriction as it only works with GOT function (I don't know how to force compiler to generate GOT function, and not sure if it's good idea for performance reason.) Also, -call-nop=* cannot pad more than 1 byte.
Ideally, I'd like to see a compiler option to pad any specific amount of bytes, and compiler will still perform all the normal function alignment.
Once I have this pad area, I can at run time to reuse these padding area to store some values or redirect the control flow.
P.S. I believe Linux kernel use similar trick to dynamically enable some software tracepoint.
-pg is intended for profile-guided optimization. The correct option for this is -fpatchable-function-entry
-fpatchable-function-entry=N[,M]
Generate N NOPs right at the beginning of each function, with the function entry point before the Mth NOP. If M is omitted, it defaults to 0 so the function entry points to the address just at the first NOP. The NOP instructions reserve extra space which can be used to patch in any desired instrumentation at run time, provided that the code segment is writable. The amount of space is controllable indirectly via the number of NOPs; the NOP instruction used corresponds to the instruction emitted by the internal GCC back-end interface gen_nop. This behavior is target-specific and may also depend on the architecture variant and/or other compilation options.
It'll insert N single-byte 0x90 NOPs and doesn't make use of multi-byte NOPs thus performance isn't as good as it should, but you probably don't care about that in this case so the option should work fine
I achieved this goal by implement my own mcount function in an assembly file and compile the code with -pg.

How do I do bcalls in hex?

So I have a TI-84 Plus C Silver Edition. I just started working on writing assembly programs on it using the opcodes. I found a good reference chart here, but was wondering how to do bcalls, specifically how to print a character to the screen. It seems as if the hex code for the call is 3 bytes long, but call takes in 2 bytes. So how do I call it?
Also, does anyone know the memory location programs are loaded into when they are run for my calculator? I haven't been able to find it yet.
Based on the definitions here: http://wikiti.brandonw.net/index.php?title=84PCSE:OS:Include_File , a "bcall" is a RST 28 instruction followed by the specific number of the bcall. So to print a character you would do (given that PutC is 44FB):
rst 28h
dw 44FBh
Presumably the character to print is in A register.
TI uses rst 28h for their bcall which translates to hexadecimal as EF. Bcalls are 2 bytes, but keep in mind that the Z80 and eZ80 are little-endian processors. So as mentioned earlier, _PutC is 44FB, so you would have to use the FB first, then the 44, making bcall(_PutC) equivalent to EFFB44.
I think the calc you are using has an eZ80. While the eZ80 is backwards compatible with the Z80 instruction set, the table to which you linked is not complete for the eZ80. If you are looking to get really wild, you can use the docs provided by Zilog here though I must warn you that if you are not fairly comfortable with Z80 Assembly, the reading material will be too dense.

Windows console application with gets() ROP exploit

I'm trying (for learning purposes) to take advantage of gets() function vulnerability using return-oriented programming (ROP) technique. The target program is a Windows console application that in some point asks for some input, and then uses gets() to store the input in the local 80 characters long array.
I created a file that contains 80 'a' characters in the beginning + some extra characters + 0x5da06c48 address for overwriting the old EIP pointer.
I'm opening the file in text editor and copy-pasting the content into the console as input. I've used IDA Pro (or OllyDbg) to set a breakpoint right after the return from the gets() function and noticed that the address was corrupted - it was set to 0x3fa03f48 (two 3f substitutions).
I've tried other addresses as well - part of them works well, but most of the times the address is being corrupted (sometimes characters missing or substituted, sometimes truncated).
How to get over this problem? Any suggestion will be highly appreciated!
Copy-Pasting binary data is hit-and-miss. Have you tried feeding the input into your test program directly from the file using input redirection?
First of all keep track of the Endianness of your platform. If you think your bits are in the right order but you are still getting malformed input, it might be that your shell/text editor isn't binary safe. You are better off writing an exploit for this flaw in a scripting language such as Python, using the Subprocess library which allows you to write data directly to an arbitrary process's stdin pipe.

EXC_BAD_ACCESS "Office for Mac 2011" Excel macros MicrosoftOleautomation debug cause

I'm encountering the ubiquitous EXC_BAD_ACCESS error in Microsoft Office for Mac 2011 on OSX 10.7 (Lion). Latest office update installed too (14.3 I believe it was)
I'm running a (rather large) macro ... Porting it from PC Office.
The error is happening when adding an element to a collection. Nothing fancy and doing it a zillion other places as well without a problem. (And haven't modified it from the working PC version).
So, while that may be the point of the error, I suspect it has to do with memory of the collection - eg, perhaps it's doing a realloc behind the scenes during this particular insert.
In particular, it's inserting the 2nd element into the collection. No user defined type. Nothing special. Adding a string element. Data being inserted is kosher. The key ID is unique. Bread and butter collection use.
Another possible suspect might be variable scope(???) ... Ie, it might be using a similarly named variable from another sub-routine or something wacky.
Or possibly the temporary string used in the sub-routine is the nominal culprit?
If I comment this line out, the rest of the macro runs okay (aside from the glitch of the missing data from the container ... Which can be empty in normal operation so that's handled okay)
I'm seeking suggestions on how to go about tracking down the issue. And tips towards resolving it.
Is the memory page 64k on mac like it is on PC?
Could it be physical ram / virtual memory / swapping? (Seems too consistent to be system os related)
Perhaps excel has a memory limit cap for macros?
How might I utilize the core dump on the exception to trace the problem?
(Experienced programmer, just unfamiliar with OSX ... And missing all my PC dev tools sigh)
Resolved.
It wasn't the collection.
Through some "printf" debuggging, tracked down the issue. Or, at least, found a solution.
The following is somewhat speculative on what was happening.
Earlier a variant array was created, populated, and passed to a subroutine ...
Dim nameList(50) As Variant
... populated ...
Call SomeSub(nameList)
...
sub SomeSub(nameList)
In the Sub, the variant array was then iterated using a "For Each" loop (which crashed)
For outerLoopIndex=0 To 100
Dim currName
For Each currName In nameList
If testName Like currName Then
addToBucket = True
Exit For ' skip any others since found a site of interest
End If
Next currName
Next outerLoopIndex
It worked correctly on the first pass of the outer loop. However, data becomes corrupted such that, on the second pass through the outer loop, the EXC_BAD_ACCESS crash occurred.
The "fix" was to explicitly declare as Variant:
Dim currName As Variant
For Each currName In nameList
...
Perhaps this will help others running into similar issues. Try explicitly declaring variables. Mac Excel seems to be more sensitive to such things. :)

Doing file operations with 64-bit addresses in C + MinGW32

I'm trying to read in a 24 GB XML file in C, but it won't work. I'm printing out the current position using ftell() as I read it in, but once it gets to a big enough number, it goes back to a small number and starts over, never even getting 20% through the file. I assume this is a problem with the range of the variable that's used to store the position (long), which can go up to about 4,000,000,000 according to http://msdn.microsoft.com/en-us/library/s3f49ktz(VS.80).aspx, while my file is 25,000,000,000 bytes in size. A long long should work, but how would I change what my compiler(Cygwin/mingw32) uses or get it to have fopen64?
The ftell() function typically returns an unsigned long, which only goes up to 232 bytes (4 GB) on 32-bit systems. So you can't get the file offset for a 24 GB file to fit into a 32-bit long.
You may have the ftell64() function available, or the standard fgetpos() function may return a larger offset to you.
You might try using the OS provided file functions CreateFile and ReadFile. According to the File Pointers topic, the position is stored as a 64bit value.
Unless you can use a 64-bit method as suggested by Loadmaster, I think you will have to break the file up.
This resource seems to suggest it is possible using _telli64(). I can't test this though, as I don't use mingw.
I don't know of any way to do this in one file, a bit of a hack but if splitting the file up properly isn't a real option, you could write a few functions that temp split the file, one that uses ftell() to move through the file and swaps ftell() to a new file when its reaching the split point, then another that stitches the files back together before exiting. An absolutely botched up approach, but if no better solution comes to light it could be a way to get the job done.
I found the answer. Instead of using fopen, fseek, fread, fwrite... I'm using _open, lseeki64, read, write. And I am able to write and seek in > 4GB files.
Edit: It seems the latter functions are about 6x slower than the former ones. I'll give the bounty anyone who can explain that.
Edit: Oh, I learned here that read() and friends are unbuffered. What is the difference between read() and fread()?
Even if the ftell() in the Microsoft C library returns a 32-bit value and thus obviously will return bogus values once you reach 2 GB, just reading the file should still work fine. Or do you need to seek around in the file, too? For that you need _ftelli64() and _fseeki64().
Note that unlike some Unix systems, you don't need any special flag when opening the file to indicate that it is in some "64-bit mode". The underlying Win32 API handles large files just fine.

Resources