The FF 15 is an absolute indirect call. It is fetching the value at a memory location, and then transferring control to the fetched address.
In order to specify that memory location precisely, the CPU needs both the segment register and the address. In the absence of an explicit request (2E for CS, for example), or a mode which has an implicit override (...
The segmentation fault error doesn't have anything to do with pushing the strings on the stack.
I used gdb to debug it, and the problem lies at:
xor ebx, ebx
Fixes the segmentation fault.
Tested on Kali Linux.
DOS didn't have a concept of more than one application being able to run at the same time, with each of those applications able to allocate memory. Programs that stayed resident after termination weren't able to allocate more memory while another program was running. So, there was no fragmentation in memory, and no "memory location that was big enough".
Generally, these are allocated regions within a debugged process. Some are heap related, some are internal to the OS's implementation, some can be pages allocated by another process that interacts with yours.
They are there because IDA needs to provide you with an interface to view memory as it's actually laid-out in memory, just like any other debugger.
Check the stack protection in the linux kernel source. The gs register gets initialized by the kernel to a percpu structure, which contains a random value that's intended to be used as stack canary. This stack canary is at offset 20 (0x14) for 32 bit programs. It's randomized for each process to avoid malware being able to rely on it being always the same ...
Your program is using a segment with base 1AD9h (the segment part of the far call). You need to create a new segment which matches it.
Start = 0x1AD90 (0x1AD9<<4)
End = 0x2AD90 [for example] (start + 64KB - maximum size)
Base = 0x1AD9
Now, go through the new segment and make sure everything makes sense. Trim the segment (reduce end ...
MZ-format executables also have the PSP at CS-0x10 just before the data loaded from the file.
Quoting Tech Help!, probaly the best DOS programming reference:
EXE-format programs define multiple program segments, including a
code, data, and stack segment. The EXE file is loaded starting at
I dealt with a ROM image once and faced this problem. I was confused too about what to do until Igor offered his advice.
What seemed to be happening was that the linker was placing every object file into its own segment, so every inter-object function invocation was rendered in the binary as a far call, where the segment base was the base given to all ...
So, a complete answer would be worth a series of blog posts but I'll try to touch the high points:
While you can use different seg:base pairs to refer to the same location, in real code it rarely happens. Code segments use the same base for all their functions and do not intersect with neighbors. However, they sometimes do not start or end at the exactly 16-...
Not an answer, really, but too long for a comment; also, i know the x86 architecture well, but have no idea about the TMS320C5, so please take this with a grain of salt.
I'm afraid that what you're trying to do doesn't match well with how IDA segmentation works, which basically stems from the 80x86 way of doing things. Which means that segment registers ...
In a DOS EXE file, if I have sub1, sub2, and sub3, split between two
code segments, how do I know which sub is in which segment?
Theoretically, you can't, since most addresses can belong to at least 16 different segments, but in practice there are some heuristics. For example, for targets of far calls and jumps you know their selector (segment value) and ...
In protected mode the segment selectors are indexes into the descriptor table (local or global one, depending on the TI bit of the selector). The descriptor entry describes the base address, limit (size) and some other attributes of the segment (data or code, 16- or 32-bit). For more info see the following links:
Global Descriptor Table;
Memory Translation ...
You're looking at 32 bit registers (probably in a 32bit process). Since 32bit processors segment registers are rarely used as offset addresses for the simple reason 32 bit is enough to represent a pretty big address range.
Instead, some segment registers (CS, SS, DS) are now used for permissions, memory protection and paging, while others are used as ...
DOS programs used segments and IDA was made to mimic that behavior. That's why you cannot change CS (since in properly set up database CS is just the segment's base) and why your changes to segment registers do now show up (because there is no segment corresponding to the values you enter).
I would suggest opening a normal (not packed) MZ file to see how it'...
Short answer: your newly created segments probably have an invalid selector value of 0, and things should start working again as soon as you set the selector to a valid value (e.g. SetSegmentAttr(here, SEGATTR_SEL, 1) at the command prompt). The reason is that all selectors created by IDA for a PE32(+) have the same base and are mostly equivalent.
The problem behind this is that each segment addresses a maximum of 64KB, and, to generate meaningful assembly, IDA needs to know what the segment registers are supposed to be when code is executed.
Assume you have the following code at linear address 0x23456:
mov bx, 6789
Which function does this call? Well, if your CS register has 0x2000, and ...
It is typically true that DOS loads a .EXE program immediately after the PSP, meaning in your terms that base - PSP == 0x0010. But it's not necessarily true, and if you were writing this (or any) DOS executable, you might do better to know this. However, this is not you. Instead, here, you are a reverse engineer - or at least trying your hand at being one. ...
Segments are still used on 64 bit long mode and are still set up, except the CPU treats their bases to be 0 (except for gs and fs), and does not perform a limit check. The default segment for rax is indeed ds, but this can be changed with a segment override. lea rdx, ds:0[rax*4] is lea rdx, ds:[rax*4 + 0], which is lea rdx, ds:[rax*4], which is the same as ...
Q1: In its manual "Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1"
Intel writes in the chapter "3.5.1 Segment Descriptor Tables":
"As with segments, the limit value is added to the base address to get
the address of the last valid byte. A limit value of 0 results in exactly one valid byte. Because ...
In addition to the answer by @user2389688 it's important to note that the syscall numbers are wrong if you're doing amd64, as are the passed in registers. Here's a 64 bit abi version which corrects the differences, and provides the intended output.
;hello3.asm attempts to make the code position independent
; rewrite of hello3.asm to use 64 bit syscall ...
I think that if you want to inject code in an elf, the best way would be to resize your second PT LOAD where the will be your loadable data, add execution permissions and inject your code at the end of the data in order to hook your elf and, at the end of this "stub" jump at the original entry point.
If you want to have an example, you can look at the code ...
Open the segments window in IDA. Go to edit that one big segment you have. Change the name to .text and edit the permissions as applicable. Uncheck "Move adjacent segments" and "Disable addresses", this step is very important, it's what prevents the actual segment data from being deleted. Change the end address to be the end of the .text segment. Click ok ...
i've always found it easier to split and join the file outside of ida to what is needed
and just create segments using edit ->segment->createSegment with proper start and end address rather that dealing with move_segment headache which will keep on saying no room blah blah , bad base blah blah etc etc ..
may be someone with better ida experience would give ...
igorsk gave a nice reply there
this post is just to illustrate how you can use some standalone disassembler framework to look for proper ljmps instead of your xxd | tr hacks
I am using capstone below
PS F:\zzzz> Get-Content .\rombi.py
from capstone import *
md = Cs(CS_ARCH_X86, CS_MODE_16)
fin = open("f:\\zzzz\\rom.bin" , "rb")
buf = fin.read()