I have an ITX industrial motherboard based on Intel HM77 which has on board GPIO pins.
I wish to enable GPIO by echo pinNumber > /sys/class/gpio/export as I normally do on Raspberry Pi. However, I can't figure out the value of pinNumber
Here's a table of available GPIO pins
Enable GPIO68
mov edx, 500h+40h
in eax, edx
mov ebx, 00000010h ; bit4, GPIO_USE_SEL3[68]
or eax, ebx ; Set bit4 of GPIO_USE_SEL3
out edx, eax
I tried using echo 68 > /sys/class/gpio/export which outputs: write error: no such device
GPIO can be used from sysfs as gpiochip180 is found in /sys/class/gpio/gpiochip180
How can I enable a GPIO pin in Linux without using assembly?
Related
i'am trying to make a simple NASM program on Linux Manjaro 20.2, the code:
section .data
global _start
_start:
mov rax, 60
mov rdi, 0
syscall
and build it up with
nasm -f elf64 test.asm
ld -o test.out test.o
./test.out
but no matter what, it always outputs Segmentation fault.
On the other side, i tried it up on Linux Mint Ulyssa and the program exits perfectly.
Using 7th gen i5 processor, nasm, ld.
Written using general purpose registers and system calls, the program runs on Ubuntu. An example is a simple hello world program.
global _start
section .text
_start:
mov eax, 0x4 ; write(int fd, char *buf, int len)
mov ebx, 0x1 ; fd
mov ecx, message ; *buf
mov edx, message_length ; len
int 0x80 ; syscall
mov eax, 0x1 ; exit(int status)
mov ebx, 0x0 ; status
int 0x80 ; syscall
section .data
message db "hello world", 0xA
message_length equ $-message
nasm -f elf64 -o hello_world.o hello_world.s
ld hello_world.o -o hello_world
./hello_world
output: hello_world
However, the program written using the intel system instructions does not work.
global _start
section .text
_start:
CLI
HLT
nasm -f elf64 halt.s -o halt.o
ld halt.o -o halt
./halt
output: Segmentation fault (core dumped)
What prevents this code from compiling this way and running?
How can this code be compiled and run?
You have two questions:
What prevents this code from compiling this way and running?
Nothing prevents it from assembling, because it is valid code.
The reason that it does not run/throws a segmentation fault is, that you are attempting to run instructions that require certain privileges in user mode.
Have a look at HLT which description states
The HLT instruction is a privileged instruction.
Also look at CLI/STI, whose situation is more complicated (which is explained in the below article and the comments below), but is also mostly useful for kernel mode code. Wikipedia says
In all three cases, only privileged applications (usually the OS kernel) may modify IF[Interrupt flag]. [...] CLI and STI are [also] privileged instructions, which trigger a general protection fault if an unprivileged application attempts to execute it, [...]
That should answer your question regarding the difference between these two instructions and why HLT surely generates a GPF (General Protection Fault) executed in User Mode.
How can this code be compiled and run?
The only way to run this code is in privileged mode. So on Windows or Linux you'd have to code a kernel driver or code your own OS to make sensible use of these instructions.
The above only applies to Protected Mode or Long Mode code.
(Real mode code may always modify IF, the Interrupt flag)
I can not produce a "Bus error" with the following assembly code. Here the memory address I use is not a legal "canonical-address". So, how can I trigger that error?
I was running this snippet of code under Ubuntu 20.04 LTS with NASM 2.14.02, but it results in a SIGSEGV segmentation fault on the load, not SIGBUS.
global _start
section .text
_start:
mov rax, [qword 0x11223344557788]
mov rax, 60
xor rdi, rdi
syscall
Corresponding X86-64 assembly code after compiling:
Disassembly of section .text:
0000000000401000 <_start>:
401000: 48 a1 88 77 55 44 33 movabs 0x11223344557788,%rax
401007: 22 11 00
40100a: b8 3c 00 00 00 mov $0x3c,%eax
40100f: 48 31 ff xor %rdi,%rdi
401012: 0f 05 syscall
If you review the Instruction Set Architecture manual for the MOV instruction you would find that accessing a non-canonical address yields a #GP(0) General Protection Fault:
Linux maps all #GP exceptions to SIGSEGV signal (Segmentation Fault). However, in Linux there is a way for a non-canonical address to cause a Bus Error and that is by getting the processor to raise an #SS (Stack Segment) exception. Linux maps #SS exceptions to the SIGBUS signal. Setting the stack pointer to a non-canonical address and then performing a stack related operation will produce such an exception.
This code should produce a Bus Error:
global _start
section .text
_start:
mov rsp, 0x8000000000000000 ; Set RSP to a non-canonical address
push rax ; Pushing value on stack should produce BUS ERROR
One other way of producing a Bus Error on Linux is to raise an #AC (Alignment Check) exception. If you write ring 3 (user) code that enables the Alignment Check bit (bit 18) in RFLAGS and do an unaligned memory access you should also receive a SIGBUS signal. This code should produce a Bus Error:
global _start
section .text
_start:
pushf ; Put current RFLAGS on the stack
or dword [rsp], 1<<18 ; Enable bit 18 (Alignment Check) of the
; RFLAGS value saved on stack
popf ; Pop new RFLAGS flags value into the RFLAGS register
mov eax, [rsp + 1] ; Move a DWORD value from unaligned address
; Should produce a BUS ERROR
I want to get a machine code of the running proccess by his PID for analysing malicious instructions, by using heuristic methods of data analysing.
All I need to know is list of current machine instructions and values of registers (EIP, EAX, EBX...).
I can use gdb for reach this goal gdb output, but is take a several problems:
I don't know how interact with gdb from my application;
malicious code can use some technics of debugger detection like this: http://www.ouah.org/linux-anti-debugging.txt
https://www.youtube.com/watch?v=UTVp4jpJoyc&list=LLw7XNcx80oj63tRYAg7hrsA
for windows;
Getting info from console output makes work of my application slower.
Is are any way to get this information by PID in Linux? Or maybe Windows?
you may have a look to gcore:
$ gcore
usage: gcore [-o filename] pid
so you can dump process core using its pid:
$ gcore 792
warning: Could not load vsyscall page because no executable was specified
0x00007f5f73998410 in ?? ()
Saved corefile core.792
and then open it in gdb:
$ gdb -c core.792
GNU gdb (GDB) Fedora 8.0.1-30.fc26
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
[...]
[New LWP 792]
Missing separate debuginfo for the main executable file
Try: dnf --enablerepo='*debug*' install /usr/lib/debug/.build-id/09/b9d38bb6291b6282de4a2692e45448828d50da
Core was generated by `./a.out'.
#0 0x00007f5f73998410 in ?? ()
(gdb) info registers
rax 0xfffffffffffffe00 -512
rbx 0x0 0
rcx 0x7f5f73998410 140047938061328
rdx 0x1 1
rsi 0x7ffd30683d73 140725415591283
rdi 0x3 3
rbp 0x7ffd30683d90 0x7ffd30683d90
rsp 0x7ffd30683d68 0x7ffd30683d68
r8 0x1d 29
r9 0x0 0
r10 0x3 3
r11 0x246 582
r12 0x4006d0 4196048
r13 0x7ffd30683e70 140725415591536
r14 0x0 0
r15 0x0 0
rip 0x7f5f73998410 0x7f5f73998410
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
or even using the binary image from /proc to get some symbols:
gdb -c core.792 /proc/792/exe
You may know that you can pass scripts to gdb, this can ease not having to interact with it from your binary (man gdb for more details).
if you don't want to use gdb directly you may try using ptrace() directly, but it is for sure more work.
For the anti debugging technics, well... they work and there is no easy way to handle them directly as far as I know, each one may be worked arounded manually, (patching binary, disassembling from unaligned addresses manually by setting then in objdump, etc...)
I'm not an expert of the domain, I hope this will help you a bit.
I have been teaching myself x86 assembly and have been looking at doing basic malloc() and free() calls. I have spent quite a bit of time searching but most examples are for 64-bit or only show the malloc call without the free, etc. I even wrote this in c, then compiled and disassembled it, which helped but gcc adds a lot of other instructions.
Here is a basic example I made of what I was able to figure out, please let me know if this is correct or if there is anything else I should be doing:
global _start
; glibc stuff
extern _malloc, _free
section .data
err: db "malloc failed!", 10, 0
.len: equ $ - err
section .bss
mptr resd 1 ;pointer to begining of malloc'd memory
section .text
_start:
push 20 ;allocate 20 bytes
call _malloc ;call malloc
add esp, 4 ;clean pushed imm
test eax, eax ;check for malloc error
jz merror
mov [mptr], eax ;store address
mov byte [eax], 0
mov byte [eax + 1], 1
push mptr ;push address
call _free ;call free
add esp, 4 ;clean push
exit:
mov eax, 0x1
int 80h
merror:
mov eax, 0x4
mov ebx, 0x1
mov ecx, err
mov edx, err.len
int 80h
jmp exit
The second part to my question is compiling it. From what I was able to find I need to link /lib/ld-linux.so.2. So in my makefile I have the following but it errors out:
mem: mem.asm
nasm -f elf mem.asm
ld -melf_i386 -lc -I /lib/ld-linux.so.2 mem.o -o mem
This is the error I get when trying to compile:
As I said I am a noob at x86 so if you also have any comments for better ways to do things I would appreciate those too! :)
UPDATE :
So I went ahead and used gcc and got that to work (without and errors at least):
mem: mem.asm
nasm -f elf mem.asm
gcc -m32 mem.o -o mem
However when I went to run it it crashed big time:
I am clearly doing something wrong with free but as I mentioned, I wasn't positive about my use of malloc and free since I couldn't find any solid examples. Any clues?
Thanks to everyone for the help! So first I was able to get the linking errors fixed by using gcc to link instead of ld:
mem: mem.asm
nasm -f elf mem.asm
gcc -m32 mem.o -o mem
In order to get that to work I needed to change the names of the functions from _malloc and _free to malloc and free. I also had to change the standard global _start to global main in order to get gcc happy. This let it compile and link without errors but as you saw in the update the program crashed horribly when it came time to free the memory.
This was because I was pushing the wrong address to the stack. I initially had the instruction push mptr but that was pushing the address of mptr to the stack rather than the address it was pointing to, hence the error. A simple update to the instruction in order to push the correct address to the stack allowed my simple program to run without errors:
push dword [mptr]
The final result:
global main
; glibc stuff
extern malloc, free
section .data
err: db "malloc failed!", 10, 0
.len: equ $ - err
section .bss
mptr resd 1 ;pointer to begining of malloc'd memory
section .text
main:
push 20 ;allocate 20 bytes
call malloc ;call malloc
add esp, 4 ;clean pushed imm
test eax, eax ;check for malloc error
jz merror
mov [mptr], eax ;store address
mov byte [eax], 0 ;store 0 at index 0
mov byte [eax + 1], 1 ;store 1 at index 1
push dword [mptr] ;push address
call free ;call free
add esp, 4 ;clean push
exit:
mov eax, 0x1
int 80h
merror:
mov eax, 0x4
mov ebx, 0x1
mov ecx, err
mov edx, err.len
int 80h
jmp exit
Thanks again to everyone for the help and thanks Peter Cordes for giving me a chance to provide a proper answer! :)
I'm sure i'll be back with more noob x86 questions as my journey continues!