section .text
global start
start:
mov eax, 29
int 80h
ret
I'm pretty sure that pause(void) is syscall 29, so why is this giving me Bus error: 10?
According to sys/syscall.h:
#define SYS_recvfrom 29
I would guess that recvfrom takes some other parameter, giving you the buss error.
If you are actually trying to call pause(void), a cursory examination of source seems to suggest that the definitions are something like the following:
syscalls.h:
#define SYS_sigsuspend 111
sigsuspend.c:
int
sigsuspend (
const sigset_t *sigmask_p
)
{
sigset_t mask;
if (sigmask_p)
mask = *sigmask_p;
else
sigemptyset(&mask);
return syscall (SYS_sigsuspend, mask);
}
sigcompat.c:
int sigpause(mask)
int mask;
{
return (sigsuspend((sigset_t *)&mask));
}
sigpause.c:
int
pause()
{
return sigpause(sigblock(0L));
}
So, while the pause(void) may not take any parameters, the syscall certainly does.
To call pause(void) from assembly, link with libc:
example.asm:
section .text
global start
start:
call pause
ret
Compile with as -o example.o example.asm and link with gcc -static -o a.out example.o
Related
In Windows, a segment error occurs when an executable file accesses a thread local variable in the dynamic library in extern mode.This problem occurs when clang is used, but not when gcc is used.
// test.c
__thread int g_cnt = 1;
Compile the dynamic library:
clang --target=x86_64-pc-windows-gnu test.c -shared -o libtest.dll
// main.c
#include <stdio.h>
extern __thread int g_cnt;
int get_cnt()
{
return g_cnt;
}
int main() {
int cnt = get_cnt();
printf("cnt = %d\n", cnt);
return 0;
}
Generating an Executable File:
clang --target=x86_64-pc-windows-gnu main.c -L.\ -ltest -o main.exe
Segment error while accessing thread local variables
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ff6bf5717e5 in get_cnt ()
(gdb) disassemble
Dump of assembler code for function get_cnt:
0x00007ff6bf5717d0 <+0>: mov 0xe8ea(%rip),%eax # 0x7ff6bf5800c0 <_tls_index>
0x00007ff6bf5717d6 <+6>: mov %eax,%ecx
0x00007ff6bf5717d8 <+8>: mov %gs:0x58,%rax
0x00007ff6bf5717e1 <+17>: mov (%rax,%rcx,8),%rax
=> 0x00007ff6bf5717e5 <+21>: mov 0x7f5782f0(%rax),%eax
0x00007ff6bf5717eb <+27>: ret
0x00007ff6bf5717ec <+28>: nopl 0x0(%rax)
End of assembler dump.
(gdb) p *0x7ff6bf5800c0
$1 = 0
Is this a clang bug?
The version of clang I tested was 12.0.1
Mingw uses x86_64-posix-seh-gcc-12.1.0-mingw-w64msvcrt-10.0.0.
This question already has answers here:
How to set gcc or clang to use Intel syntax permanently for inline asm() statements?
(2 answers)
Can I use Intel syntax of x86 assembly with GCC?
(2 answers)
Closed last year.
I'd like to use intel syntax gcc inline assembly, leaving gcc's default -masm=att dialect untouched.
The following code works fine:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a = 123;
int b = 0;
printf("before: a = %d\n", a);
printf("before: b = %d\n", b);
__asm__ __volatile__ (
".intel_syntax noprefix\n\t"
"mov eax, %[a]\n\t"
"mov %[b], eax\n\t"
".att_syntax prefix\n\t"
: [b]"+r"(b)
: [a]"r"(a)
: "eax"
);
printf("after: a = %d\n", a);
printf("after: b = %d\n", b);
return 0;
}
// before: a = 123
// before: b = 0
// after: a = 123
// after: b = 123
But if i change Output Operands Constraint from register('r') to memory('m'), error occurs:
Error: junk `(%rbp)' after expression
In the generated assembly file, I find this:
#APP
.intel_syntax noprefix
mov eax, -16(%rbp)
mov -12(%rbp), eax
.att_syntax prefix
#NO_APP
It looks like gcc renders Assembler Template using AT&T Effective-Address dialect.
I searched the web, Extended Asm shows something like "Multiple assembler dialects in asm templates" and "x86 Operand Modifiers", but I still didn't solve the problem.
Is there a way to tell gcc, (maybe some instructions around __asm__, telling gcc to do operand-substitution with Intel-syntax addressing modes temporarily, like -masm=intel do in the whole file), render the Assembler Template using Intel Effective-Address dialect temporarily in __asm__ () block, not the whole file, like this:
#APP
.intel_syntax noprefix
mov eax, [%rbp - 16]
mov [%rbp - 12], eax
.att_syntax prefix
#NO_APP
Ok so basically I was just writing a C program to build my object files and then create executeables from them by using nasm and ld respectively
The program I wrote makes the correct calls to nasm and ld but I either compile fine with -f win32/win64 ( I'm on a 64 bit windows 7 machine ) or fail with the other options which is fine though... right? If the program compiles and creates the exe it runs and immediately crashes without printing the Hello World message. I'd Really like to jump into assembly. Some Help ?
section .text
global _start ;must be declared for linker (ld)
_start: ;tells linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov ah,00
int 16h
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello, world!', 0xa ;our dear string
len equ $ - msg ;length of our dear string
I also happen to have a kali system ; I don't suppose I could compile for both operating systems without using Wine?
So my C program is working nicely! I can't find any examples of code to assemble though. Well I can... but it all fails. Does anyone have a link?
#include <stdio.h>
#include <stdlib.h>
#include <CustomHeader_Small.h>
void Assemble(void);
void PrintMenu(void);
void LoadOptions(void);
void SaveOptions(void);
char TempBuff[255];
char Format[30];
void SaveOptions(void)
{
FILE *Source = fopen("Settings.ini","w");
if(Source)
{
printf("%s","Enter A Format Type ->");
scanf("%s",Format); //Save Format
fprintf(Source,"Format:%s",Format);
fclose(Source);
puts("Settings Updated!");
LoadOptions();
}
return;
}
void LoadOptions(void)
{
FILE *Source = fopen("Settings.ini","r");
if(Source)
{
char ch;
int i;
char Line[50];
fscanf(Source,"%s",Line);
CCopy(Line,CPos(Line,":",0)+1,CLen(Line),Format,0,1);
free(Line);
}
else
{
Source = fopen("Settings.ini","w");
fprintf(Source,"%s","Format:Win32");
fclose(Source);
}
PrintMenu();
LoadOptions();
return;
}
void PrintMenu(void)
{
printf("%s","Menu:\n________\n1.) [C]reate A New Project.\n2.) [O]pen A Project.\n3.) [A]ssemble A Project.\n4.) [E]dit Settings\n");
printf("%s","5.) [Q]uit\n");
return;
}
void Assemble(void)
{
char *File=malloc(256);
printf("Note : Compiling In %s Mode\n",Format);
printf("%s","Enter A Project Name -> ");
scanf("%s",File);
char *Command;
int ch;
while((ch=getchar())!='S')
{
Command=malloc(1024);
strcpy(Command,"H:\\Users\\Grim\\AppData\\Local\\nasm\\nasm.exe -f ");
strcat(Command,Format);
strcat(Command," ");
strcat(Command,File);
strcat(Command,"\\");
strcat(Command,File);
strcat(Command,".asm ");
strcat(Command,"-o ");
strcat(Command,File);
strcat(Command,"\\");
strcat(Command,File);//This Creates The Object File Using Nasm ( Not Just Yet But Were Well On Our Way!
strcat(Command,".o");
system(Command); //Calls Nasm.
free(Command);
Command=malloc(1024);
strcpy(Command,"H:\\MinGW\\bin\\ld.exe ");
strcat(Command,File);
strcat(Command,"\\");
strcat(Command,File);
strcat(Command,".o ");
strcat(Command,"-o ");
strcat(Command,File);//This Creates The Executable File Using Nasm ( Not Just Yet But Were Well On Our Way!
strcat(Command,"\\");
strcat(Command,File);
strcat(Command,".exe");
system(Command); //Calls Nasm.
free(Command);
puts("Press Enter To Compile Again But Enter An [S] Followed By Enter To [S]top.");
}
free(File);
puts("NasmWrapper Assembly Done!");
printf("%s","\n\n\n");
PrintMenu();
return;
}
int main()
{
LoadOptions();
char ch;
while((ch = getchar())!='Q')
{
if(ch=='A') Assemble();
if(ch=='E') SaveOptions();
}
return 0;
}
Also any comments on the C program would be nice :D Thanks for explaining how to use the [Code] thing.
Your assembly program, apart from that odd int 16h* is specifically for Linux (32-bit Linux, to be more precise). int 0x80 is the way you invoke one of the Linux kernel system calls.
Windows doesn't do it this way. Instead you call the Windows API or the C standard library.
This OS-specific variation is one of the reasons it is good to use a higher level language rather than assembly.
If you want to play with assembly, my recommendation would be to decide on which OS you want to start with, and use that exclusively to begin with. Find some tutorials (there are lots for Linux and Windows) and get started. Once you have got it working for one OS, try it for another.
* int 16h calls the BIOS from DOS. This won't work in Linux.
This is about finding the Fibonacci number using recursive approach which I had asked
in my previous question. Using one of the solution(answered), the run time taken
by the program was almost 0. I attach the program in GDB and check the assembly instruction
and found the following:
#include<iostream>
template<size_t N>
struct fibonacci:std::integral_constant<size_t,fibonacci<N-1>{}+fibonacci<N-2>{}>{};
template<> struct fibonacci<1> : std::integral_constant<size_t,1> {};
template<> struct fibonacci<0> : std::integral_constant<size_t,0> {};
int main() {
int out = 0;
constexpr int number = 40;
out = fibonacci<number>();
std::cout<<"Fibonacci Series Of "<<number<<" is "<<out<<std::endl;
}
I have compiled my program using following flags and assembly instruction
of my program is as:
$g++ -g -gdwarf-2 -Wall -fdump-tree-all -std=c++11 fibonacci.cpp -o
fibcpp
(gdb) disassemble main
Dump of assembler code for function main():
0x0000000000400890 <+0>: push %rbp
0x0000000000400891 <+1>: mov %rsp,%rbp
0x0000000000400894 <+4>: sub $0x10,%rsp
0x0000000000400898 <+8>: movl $0x0,-0x8(%rbp)
0x000000000040089f <+15>: movl $0x28,-0x4(%rbp)
0x00000000004008a6 <+22>: lea -0x9(%rbp),%rax
0x00000000004008aa <+26>: mov %rax,%rdi
=> 0x00000000004008ad <+29>: callq 0x400952 <std::integral_constant<unsigned long, 102334155ul>::operator unsigned long() const>
0x00000000004008b2 <+34>: mov %eax,-0x8(%rbp)
0x00000000004008b5 <+37>: mov $0x400a15,%esi
we can see that(on the arrowed==>) 102334155 is there which is fibonacci(40). This indicates that indeed all calculation has happened in the compile time.
When we compile our program and put extra flag(-fdump-tree-all), we get many
internal files and normally(fibonacci.gimple) files are the one where normally template
instantiated code would go. However in this case I did not find anything
related to this calculation in fibonacci.gimple file.
My question is in which file g++ does calculate and store these information?. My aim over here is to understand more about compile time calculation/manipulation which happens in C++ program.
From you disassembly it seems, that the "method" operator unsigned long() is called and not inlined. When you look at its disassembly, you should see the actual returned value. It is the instantiation of integral_constant<>::operator value_type() with size_t = unsigned long as value_type.
But you might already know all that... You want to actually see it. The message https://gcc.gnu.org/ml/gcc/2011-06/msg00110.html suggests, that others thought about an -ftrace-template-instantiation option, but no one implemented it, yet.
EDIT: There is lots of information about debugging and tracing templates in this question.
How can I find the in-memory address (for exploit writing) of a specific instruction?
Specifically, I'm looking for a call ebp instruction in user32.dll on Windows XP with no Service Pack whose address I can point EIP to. I have both Immunity Debugger and OllyDBG installed on the target.
To find an instruction, you need to figure out where the code, .text, section starts and ends, then load the DLL and just do liner search until you find the instruction.
Here we have a test DLL that has two call ebp instructions:
// test.c
// gcc -Wall -shared test.c -o test.dll
#include <stdio.h>
__declspec(dllexport) void test(void) {
asm("call *%ebp");
puts("test");
asm("call *%ebp");
}
Compile it and load the DLL in ollydbg and click CTRL+F and search for CALL EBP:
6BEC125A |. FFD5 CALL EBP
6BEC125C |. C70424 6430EC6> MOV DWORD PTR SS:[ESP],test.6BEC3064 ; |ASCII "test"
6BEC1263 |. E8 74060000 CALL <JMP.&msvcrt.puts> ; \puts
6BEC1268 |. FFD5 CALL EBP
you see the address of the first instruction is at 0x6bec125a the second at 0x6bec1268. The opcode of call ebp is 0xff 0xd5, remember this.
Now we need to find the boundaries of the code, you can use objdump with -h:
> objdump --headers test.dll
test.dll: file format pei-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000984 6bec1000 6bec1000 00000600 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
1 .data 00000008 6bec2000 6bec2000 00001000 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .rdata 0000011c 6bec3000 6bec3000 00001200 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
....
>
the code starts at VMA, virtual memory address, 0x6bec1000 and its size is 0x984, so it ends at 0x6bec1000 + 0x984 = 0x6bec1984 as :
0x6bec1000
....
what is between are the DLL instructions
....
0x6bec1984
I hope that was clear so far.
If we want to code our call ebp scanner, we need to do the flowing:
Read the PE information and get the executable section information, usually .text, to find its relative address and its virtual size.
Load the DLL using LoadLibrary, it will return the base address of the DLL.
The virtual address of the beginning of the code section is: DLL base address + code section virtualAddress and it ends at DLL base address + code section virtualAddress + VirtualSize.
Now we are ready to loop through the code and look for 0xff 0xd5, call ebp's opcode, simple liner search.
Here is a simple implementation:
// findopcode.c
// gcc -Wall findopcode.c -o findopcode
#include <windows.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
const char opcode[] = {0xff, 0xd5}; // The opcode of `call ebp'
FILE *dllFile;
HMODULE dllHandle;
IMAGE_DOS_HEADER dosHeader;
IMAGE_NT_HEADERS NtHeaders;
IMAGE_SECTION_HEADER sectionHeader;
unsigned int i;
unsigned char *starAddr;
unsigned char *endAddr;
if( argc < 2 ) {
printf("usage: %s [DLL]\n", argv[0]);
return -1;
}
if( ( dllFile = fopen(argv[1], "rb") ) == NULL ) {
perror("[!] Error");
return -1;
}
// Read the basic PE headers
fread(&dosHeader, sizeof(dosHeader), 1, dllFile);
fseek(dllFile, dosHeader.e_lfanew, SEEK_SET);
fread(&NtHeaders, sizeof(NtHeaders), 1, dllFile);
// Search for the executable section, .text section.
for( i = 0 ; i < NtHeaders.FileHeader.NumberOfSections ; i++ ) {
fread(§ionHeader, sizeof(sectionHeader), 1, dllFile);
// If we found a section that contains executable code,
// we found our code setion.
if( (sectionHeader.Characteristics & IMAGE_SCN_CNT_CODE) != 0 ) {
printf("[*] Code section: `%s'\n", sectionHeader.Name);
break;
}
}
fclose(dllFile);
// Load the DLL to get it's base address
if( (dllHandle = LoadLibraryA(argv[1])) == NULL ) {
printf("[!] Error: loading the DLL, 0x%.8x\n", (unsigned int) GetLastError());
return -1;
}
// The code start at : base address + code virtual address
starAddr = (unsigned char *) dllHandle + sectionHeader.VirtualAddress;
// It ends at : base address + code virtual address + virtual size
endAddr = (unsigned char *) starAddr + sectionHeader.Misc.VirtualSize;
printf("[*] Base address : 0x%.8x\n", (unsigned int) dllHandle);
printf("[*] Start address: 0x%.8x\n", (unsigned int) starAddr);
printf("[*] End address : 0x%.8x\n", (unsigned int) endAddr);
// Simple liner search, when ever we find `0xff 0xd5' we print that address
for( endAddr -= sizeof(opcode) ; starAddr < endAddr ; starAddr++ ) {
if( memcmp(&opcode, (void *) starAddr, sizeof(opcode)) == 0 ) {
printf("[*] Found `call ebp` at: 0x%.8x\n", (unsigned int) starAddr);
}
}
FreeLibrary(dllHandle);
return 0;
}
Compile it and test it with that DLL:
> gcc -Wall findopcode.c -o findopcode
> findopcode.exe test.dll
[*] Code section: `.text'
[*] Base address : 0x6bec0000
[*] Start address: 0x6bec1000
[*] End address : 0x6bec1984
[*] Found `call ebp` at: 0x6bec125a
[*] Found `call ebp` at: 0x6bec1268
>
It works pretty well, let's try user32.dll:
> findopcode.exe \Windows\System32\user32.dll
[*] Code section: `.text'
[*] Base address : 0x75680000
[*] Start address: 0x75681000
[*] End address : 0x756e86ef
[*] Found `call ebp` at: 0x756b49b5
>
I only found one call ebp at 0x756b49b5. Note, you way want to check if you have a read access before you read with memcmp using IsBadReadPtr:
if( IsBadReadPtr(starAddr, sizeof(opcode)) == 0 &&
memcmp(&opcode, (void *) starAddr, sizeof(opcode)) == 0 ) {
so the program won't fail if you hit some area with some weird access.
An alternative way is to use the msfpescan from the metasploit framework:
msfpescan -j ebp user32.dll