Why am I getting an unexpected `0xcc` byte when loading nearby code bytes? Is it because of segment register %es? - debugging

I got some inconsistent result of instruction.
I don't know why this happens, so I suspect %es register is doing something weird, but I'm not sure.
Look at below code snippet.
08048400 <main>:
8048400: bf 10 84 04 08 mov $HERE,%edi
8048405: 26 8b 07 mov %es:(%edi),%eax # <----- Result 1
8048408: bf 00 84 04 08 mov $main,%edi
804840d: 26 8b 07 mov %es:(%edi),%eax # <----- Result 2
08048410 <HERE>:
8048410: 11 11 adc %edx,(%ecx)
8048412: 11 11 adc %edx,(%ecx)
Result 1:
%eax : 0x11111111
Seeing this result, I guessed that mov %es:(%edi),%eax to be something like mov (%edi),%eax.
Because 0x11111111 is stored at HERE.
Result 2:
%eax : 0x048410cc
However, the result of Result 2 was quite different.
I assumed %eax to be 0x048410bf, because this value is stored at main.
But the result was different as you can see.
Question:
Why this inconsistency of the result happens?
By the way, value of %es was always 0x7b during execution of both instruction.

es is a red herring. The difference you see is 1 byte at main, cc vs. bf. That is because you used a software breakpoint at main and your debugger inserted an int3 instruction which has machine code cc temporarily overwriting your actual code.
Do not set a breakpoint where you intend to read from, or use a hardware breakpoint instead which does not modify code.

Related

Assembly debugging issue

So I have the assembly code below and the goal is to run the code without hitting the explode bomb call. The user enters 6 numbers with spaces in between but that part isn't too important as it is mostly handled by the read six numbers function which is known to be good and not explode the bomb.
0x0000000000400f0c <+0>: push %rbp
0x0000000000400f0d <+1>: push %rbx
0x0000000000400f0e <+2>: sub $0x28,%rsp
0x0000000000400f12 <+6>: mov %rsp,%rsi
0x0000000000400f15 <+9>: callq 0x4015da <read_six_numbers>
0x0000000000400f1a <+14>: cmpl $0x0,(%rsp)
0x0000000000400f1e <+18>: jne 0x400f27 <phase_2+27>
0x0000000000400f20 <+20>: cmpl $0x1,0x4(%rsp)
0x0000000000400f25 <+25>: je 0x400f48 <phase_2+60>
0x0000000000400f27 <+27>: callq 0x4015a4 <explode_bomb>
0x0000000000400f2c <+32>: jmp 0x400f48 <phase_2+60>
0x0000000000400f2e <+34>: mov -0x8(%rbx),%eax
0x0000000000400f31 <+37>: add -0x4(%rbx),%eax
0x0000000000400f34 <+40>: cmp %eax,(%rbx)
0x0000000000400f36 <+42>: je 0x400f3d <phase_2+49>
0x0000000000400f38 <+44>: callq 0x4015a4 <explode_bomb>
0x0000000000400f3d <+49>: add $0x4,%rbx
0x0000000000400f41 <+53>: cmp %rbp,%rbx
0x0000000000400f44 <+56>: jne 0x400f2e <phase_2+34>
0x0000000000400f46 <+58>: jmp 0x400f54 <phase_2+72>
0x0000000000400f48 <+60>: lea 0x8(%rsp),%rbx
0x0000000000400f4d <+65>: lea 0x18(%rsp),%rbp
0x0000000000400f52 <+70>: jmp 0x400f2e <phase_2+34>
0x0000000000400f54 <+72>: add $0x28,%rsp
0x0000000000400f58 <+76>: pop %rbx
0x0000000000400f59 <+77>: pop %rbp
0x0000000000400f5a <+78>: retq
I know that the read 6 numbers part works fine and doesnt set off the bomb. All it does is get the input.
Hey I'm not real good at assembly but I'm working on this and I think I've figured out the first number is 0 and the second is 1 but that could be wrong. I see the comparison on line +14 but im not sure if thats comparing the first value or just making sure that the string the user entered wasnt empty. I know you're supposed to put in 6 numbers and that's only the first 2 though. I'm a bit confused about what lines +34 to +40 do. I get that that's where the compared numbers change but I'm not sure how it affects them. If anyone is good with assembly and can help me out that would be awesome.

power8 assembly code with shared build issue with save and restore of TOC

I have the following assembly code
.machine power8
.abiversion 2
.section ".toc","aw"
.section .text
GLOBAL(myfunc)
myfunc:
stdu 1,-240(1)
mflr 0
std 0, 0*8(1)
mfcr 8
std 8, 1*8(1)
std 2, 2*8(1)
# Save all non-volatile registers R14-R31
std 14, 4*8(1)
...
# Save all the non-volatile FPRs
...
stwu 1, -48(1)
bl function_call
nop
addi 1, 1, 48
ld 0, 0*8(1)
mtlr 0
ld 8, 1*8(1)
ld 2, 2*8(1)
...
# epilogue, restore stack frame
This works fine with static build but shared build gives segmentation fault in
00000157.plt_call.__tls_get_addr_opt##GLIBC_2.22, should the shared build be handled differently in power8 w.r.t TOC?
The calling convention is the same between POWER 8 and previous processors. However, there has been changes with regards to the TOC pointer (r2) handling between ABIv1 and ABIv2.
In ABIv2, the caller does not establish the TOC pointer in r2; the called function should do this for global entry points (ie, where the TOC pointer may not be the same as that used in the callee). To do this, ABIv2 functions will have a prologue that sets r2:
0000000000000000 <foo>:
0: 00 00 4c 3c addis r2,r12,0
4: 00 00 42 38 addi r2,r2,0
- this depends on r12 containing the address of the function's global entry point (those 0 values will be replaced with actual offsets at final link time).
I don't see any code setting r12 appropriately in your example. Are you sure you're complying with the v2 ABI there?
The ABIv2 spec is available here: https://members.openpowerfoundation.org/document/dl/576 Section 2.3.2 will be the most relevant for this issue.

Encoding conditional jump (jecxz) within inline assembly

I am trying encode a jecxz instruction within inline assembly. The jexcz should jump to the next immediate instruction (i.e: the nop).
int main() {
asm("lea -24(%rdi), %rcx");
asm("jecxz $0x00");
asm("nop");
}
But I am getting the following error.
gcc -o t main.c
main.c: Assembler messages:
main.c:7: Error: operand type mismatch for `jecxz'
What needs to be fixed here?
The most compatible solution is to write the line as follows:
asm("jecxz nextline; nextline:");
Regarding the asm("jecxz .+3") solution:
In 16-bit mode, a jcxz is encoded as e3 XX and a jecxz is encoded as 67 e3 XX
In 32-bit mode, a jecxz is encoded as e3 XX and a jcxz is encoded as 67 e3 XX
In 64-bit mode, a jrcxz is encoded as e3 XX and a jecxz is encoded as 67 e3 XX (jcxz is not available)
(Where XX is a signed-byte offset from the end of the instruction to the jump target)
So then, the line asm("jecxz .+3"); would assemble to 67 e3 00 in 16-bit and 64-bit code, and e3 01 in 32-bit code. The 32-bit case would be incorrect, as it would jump one byte past the end of the instruction, given that the 32-bit form is only two bytes wide.
If we use a label, we cover all three cases.
As per Micheal Petch's comment the correct usage is
asm("jecxz .+3");
which encodes the relative distance to the next immediate instruction.

How to determine the major compiler version from .obj files compiled with /GL?

I'm trying to determine Visual Studio version (2002/2003, 2005, 2008, 2010, 2012, 2013, 2015) from the .obj file generated with the link time code generation option.
The file I have, generated with MSVC2012, has following COFF header contents:
File Header
+0 00 00 Machine - Unknown Machine
+2 FF FF NumberOfSections
+4 01 00 4C 01 TimeDateStamp
+8 70 94 F9 55 PointerToSymbolTable
+12 38 FE B3 0C NumberOfSymbols
+16 A5 D9 SizeOfOptionalHeader
+18 AB 4D Characteristics
Optional Header
+20 AC 9B Magic
+22 D6 B6 Linker Version Major/Minor
It seems that the initial 4 bytes being 00,00,FF,FF mark it as a LTCG object, and what follows is proprietary. None of the usual file header members make "sense" (maybe the timestamp is OK, I didn't check).
Does anyone know offhand if any part of this header is compiler-specific? All I need to determine is the MSVC major version used to compile the object...
It appears that there is a version, coded as <MAJOR:16:LE> 0x80 <MINOR:16:LE>, stored shortly after the header. E.g.:
17.00.61030 -> 0x11.0xEE66 -> 11 00 80 66 EE
19.00.23026 -> 0x13.0x59F2 -> 13 00 80 F2 59
What's needed is to figure out how to get to it reliably by offsets from preceding data.
This is a related question, with no resolution...
TL,DR :
You can't get the compiler version with this file format, I guess ...
Complete answer :
It looks like some variation of the "anonymous file format", described in the "winnth.h" by various ANON_OBJECT_HEADER_XXX structures (replace XXX by V2 or BIGOBJ).
Here is a copy of the ANON_OBJECT_HEADER_BIGOBJ found in winnt.h :
typedef struct ANON_OBJECT_HEADER_BIGOBJ {
/* same as ANON_OBJECT_HEADER_V2 */
WORD Sig1; // Must be IMAGE_FILE_MACHINE_UNKNOWN
WORD Sig2; // Must be 0xffff
WORD Version; // >= 2 (implies the Flags field is present)
WORD Machine; // Actual machine - IMAGE_FILE_MACHINE_xxx
DWORD TimeDateStamp;
CLSID ClassID; // CLSID is a 16 bytes struct (not original comment)
DWORD SizeOfData; // Size of data that follows the header
DWORD Flags; // 0x1 -> contains metadata
DWORD MetaDataSize; // Size of CLR metadata
DWORD MetaDataOffset; // Offset of CLR metadata
/* bigobj specifics */
DWORD NumberOfSections; // extended from WORD
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
} ANON_OBJECT_HEADER_BIGOBJ;</code>
The description match:
Sig1 : 00 00
Sig2 : FF FF
Version : >=2
Machine : 0x14c`
The other header structures (i.e, ANON_OBJECT_HEADER and ANON_OBJECT_HEADER_V2) are basically the same, but with less fields.
For the Version field, I found some information here :
http://www.geoffchappell.com/studies/msvc/link/dump/infiles/obj.htm
Looks like the Version field is "1" for anonymous files, and it seems like the anonymous files and the so called "import files" shared the same characteristics, only that Version = 0 for import file format (I do not really know what it is admittedly).
But yeah, by just looking at the header, it seems that we have no information on what compiler version was used. And even then, when looking at .obj files generated with the /GL switch, they do not exactly follow this format and I didn't find much information about them. I'll be glad that someone prove me wrong.

Understand VB6 disassemble code

I have an old VB executable that has been used for a long time in my project.
The current implementation of the application contains a debug window that's
not needed any more.
Of course, the source code was lost and can not be modified.
My idea is to modify the HEX code of the instance that's opening the annoying debug window.
For that purpose, I use VB Decompiler by DotFix software, and I suppose that I found the code responsible for that instance. Unfortunately, I can't understand how it works.
Let's see the disassemble code:
loc_8F420C: var_8A = 0
loc_8F4219: If (Len(var_88) = &H30) Then
loc_8F4225: Call {3014B1BF-8A2C-23D7-B50400C24F280C20}.Method_arg_12 (var_88)
loc_8F4233: Call {3014B1BF-8A2C-23D7-B50400C24F280C20}.Method_arg_16 (var_108)
loc_8F423D: If CBool(var_108) Then
loc_8F424D: Me.Global.Unload Me
loc_8F4258: Else
loc_8F425A: var_8A = &HFF
...
loc_8F43B0: End If
loc_8F43B3: Else
At the first sight var_108 seems a bool variable that is the one setting the debug window. Can I implicitly put in loc_8F423D: If CBool(false/true) Then to stop this window from launching?
Can anyone explain to me what are those Call {#######-####-####-################}.Method_arg_## from above?
PEiD detect compiler:
Microsoft Visual Basic 5.0 / 6.0 [Overlay]
Part 2:
It took me a long time to get the new idea - the right one, possibly. Let's take a look at the assembly code:
004F420C: 70 FStI2 var_8A <- loc_8F420C: var_8A = 0
Looks like loc_8F4219: If (Len(var_88) = &H30) Then
004F420F: 6C ILdRf var_88
004F4212: 4A FnLenStr Len()
004F4213: F5 LitI4: 48 (0x30)
Let's find the next code snippets:
004F4218: C7 EqI4 =
004F4219: 1C BranchF 004F43B3
Our Call methods looks like :
004F421C: 6C ILdRf var_88 < - (var_88) from Call
004F421F: 22 ImpAdLdPr
004F4222: 58 MemLdPr
004F4225: 0D VCallHresult var_88.vtable[12] <- Method_arg_12
004F422A: 04 FLdRfVar var_108 <- (var_108) possible CALL/BACK
004F422D: 22 ImpAdLdPr
004F4230: 58 MemLdPr
004F4233: 0D VCallHresult var_108.vtable[16] <- Method_arg_16
004F4238: 6C ILdRf var_108 <- (var_108) 70% sure is RESPONSE(true/false)
And now the most interesting parts of that annoying P-Code&Assembly, we find the if instance that verifies if the Debug Windows is needed. If we look at P-Code we can see that if has the form:
loc_8F423D: If CBool(var_108) Then
loc_8F424D: Me.Global.Unload Me
loc_8F4258: Else
loc_8F425A: var_8A = &HFF
And now look at the Address - if is true execute address 00F424D / 8F424D else jump outside to 004F4258
004F423B: FC52 CBoolI4
004F423D: 1C BranchF 004F4258
004F4240: 6C ILdRf param_8
004F4243: FD9C FStAdNoPop
004F4247: 05 ImpAdLdRf
004F424A: 24 NewIfNullPr GLOBAL
004F424D: 0D VCallHresult Global._Unload(object As IDispatch)
004F4252: 1A FFree1Ad var_90
004F4255: 1E Branch 004F43B0
004F4258: loc_004F423D
004F4258: F4 LitI2_Byte: 255 (True)
Possibly, if I change the 004F423D: 1C BranchF 004F4258 so that it points to another address 004F424D, logically that might do the trick.
004F423D: 1C BranchF 004F424D
Now I'm trying to find that address with OllyDbg - to test if that helps. If I succeed I will write part 3.
Does anyone have some other ideas?

Resources