15 Ekim 2019 Salı

objdump komutu

Giriş
elf dosyasının veya .o dosyasının sembollerine objdump ile bakılabilir. Komutun bir çok seçeneği var.

Diğer Araçlar
Bu araç ile ilgili diğer araçların açıklaması şöyle.
ar: creates static libraries.

objdump: this is the most important binary tool; it can be used to display all the information in an object binary file.

strings: list all the printable strings in a binary file.

nm: lists the symbols defined in the symbol table of an object file.

ldd: lists the shared libraries on which the object binary is dependent.

strip: deletes the symbol table information.
-d disassamble seçeneği
Assembly kodunu çıkartır.
Örnek
Şöyle yaparız.
objdump -d a.o
veya şöyle yaparız
objdump -d foo.exe
Örnek
Şöyle derlenmiş bir .o dosyası olsun
gcc -c test.c
Bu dosyanın tamamına şöyle bakarız.
objdump -D test.o
Çıktı olarak şuna benzer bir şey görürüz.
0:   14 00                   adc    $0x0,%al
--disassembler-options seçeneği
Üretilen assembly kodunun att veya intel formatında olmasını sağlar. Bu seçenek sanırım -M intel ile aynı. Şöyle yaparız.
$ objdump -d --disassembler-options=att code.c
  ...
 080483c4 :
 80483c4:   8d 4c 24 04           lea    0x4(%esp),%ecx
 80483c8:   83 e4 f0              and    $0xfffffff0,%esp
 80483cb:   ff 71 fc              pushl  -0x4(%ecx)
 80483ce:   55                    push   %ebp
 80483cf:   89 e5                 mov    %esp,%ebp
 80483d1:   51                    push   %ecx
 80483d2:   83 ec 04              sub    $0x4,%esp
 80483d5:   c7 04 24 b0 84 04 08  movl   $0x80484b0,(%esp)
 80483dc:   e8 13 ff ff ff        call   80482f4 
 80483e1:   b8 00 00 00 00        mov    $0x0,%eax
 80483e6:   83 c4 04              add    $0x4,%esp 
 80483e9:   59                    pop    %ecx
 80483ea:   5d                    pop    %ebp
 80483eb:   8d 61 fc              lea    -0x4(%ecx),%esp
 80483ee:   c3                    ret
 80483ef:   90                    nop
veya şöyle yaparız.
$ objdump -d --disassembler-options=intel code.c
  ...
 080483c4 :
 80483c4:   8d 4c 24 04           lea    ecx,[esp+0x4]
 80483c8:   83 e4 f0              and    esp,0xfffffff0
 80483cb:   ff 71 fc              push   DWORD PTR [ecx-0x4]
 80483ce:   55                    push   ebp
 80483cf:   89 e5                 mov    ebp,esp
 80483d1:   51                    push   ecx
 80483d2:   83 ec 04              sub    esp,0x4
 80483d5:   c7 04 24 b0 84 04 08  mov    DWORD PTR [esp],0x80484b0
 80483dc:   e8 13 ff ff ff        call   80482f4 
 80483e1:   b8 00 00 00 00        mov    eax,0x0
 80483e6:   83 c4 04              add    esp,0x4
 80483e9:   59                    pop    ecx
 80483ea:   5d                    pop    ebp
 80483eb:   8d 61 fc              lea    esp,[ecx-0x4]
 80483ee:   c3                    ret

 80483ef:   90                    nop
-f seçeneği - file-headers
.so dosyasının hangi ABI türünü kullandığını gösterir.
% objdump -f /lib/ld-linux.so.2 
             /lib64/ld-linux-x86-64.so.2  
             /libx32/ld-linux-x32.so.2

/lib/ld-linux.so.2:     file format elf32-i386
architecture: i386, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00000a90


/lib64/ld-linux-x86-64.so.2:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000000c90


/libx32/ld-linux-x32.so.2:     file format elf32-x86-64
architecture: i386:x64-32, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00000960
-S seçeneği
Açıklaması şöyle. -d seçeği ile birlikte kullanılır
>objdump --help
[...]
-S, --source             Intermix source code with disassembly
-l, --line-numbers       Include line numbers and filenames in output
Örnek
Şöyle yaparız.
> objdump -d -M intel -S test.o

test.o:     file format elf32-i386


Disassembly of section .text:

00000000 <main>:
#include <stdio.h>

int main(void)
{
   0:   55                    push   ebp
   1:   89 e5                 mov    ebp,esp
   3:   83 e4 f0              and    esp,0xfffffff0
   6:   83 ec 10              sub    esp,0x10
    puts("test");
   9:   c7 04 24 00 00 00 00  mov    DWORD PTR [esp],0x0
  10:   e8 fc ff ff ff        call   11 <main+0x11>

    return 0;
  15:   b8 00 00 00 00        mov    eax,0x0
}
  1a:   c9                    leave  
  1b:   c3                    ret
-t seçeneği
Sembolleri gösterir

Örnek
Şöyle yaparız
objdump -t x.sm
Örnek
Elimizde şöyle bir kod olsun.
#include <stdio.h>
int g_a;
int g_b;
int g_c;

int main()
{
    printf("Hello world\n");
    return 0;
}
Şöyle yaparız.
objdump -t myapp
Çıktı olarak şunu alırız.
00004020 g_b
00004024 g_a
00004028 g_c
Örnek
Sembollerin hangi elf bölümüne geldiği görmek için şöyle yaparız. .text ve .rodata bölümlerinde tanımlı semboller görülebilir.
$ objdump -T /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 | grep "chrono"
00080828 g    DF .text      0000002a  GLIBCXX_3.4.11 _ZNSt6chrono12system_clock3nowEv
0008ae38 g    DO .rodata    00000001  GLIBCXX_3.4.11 _ZNSt6chrono12system_clock12
Örnek
Eğer bir sembol yoksa undefined olarak belirtilir.
$ objdump -T myapp | grep "GLIBCXX_3.4.19"
00000000      DF *UND*  00000000  GLIBCXX_3.4.19 _ZNSt6chrono3_V212system_clock3n
-x seçeneği
Elimizde şöyle bir kod olsun.
// main.c
extern int x;
static int *y = &x;
int main() { 
  return *y;
}
Şöyle yaparız
objdump -x main.o
Çıktı olarak şunu alırız.
RELOCATION RECORDS FOR [.data]:
OFFSET           TYPE              VALUE
0000000000000000 R_X86_64_64       x



14 Ekim 2019 Pazartesi

openssl rsa aracı - Public/Private Key Oluşturur

genrsa seçeneği
Private key oluşturur deniliyor. Ancak aslında oluşturulan pem dosyasında hem private hem de public key bulunur. Public key'in başka bir komutla dışarıya aktarılması gerekebilir. Açıklaması şöyle. PEM dosyası ASCII tabanlıdır ancak Base64 kullanılarak yazıldığı için gözle okunamazlar.
This command generates a private key in your current directory named yourdomain.key (-out yourdomain.key) using the RSA algorithm (genrsa) with a key length of 2048 bits (2048). The generated key is created using the OpenSSL format called PEM.
Örnek
Şöyle yaparız.
openssl genrsa -out private.pem 2048
Örnek
Şöyle yaparız.
openssl genrsa -out baseKey.pem
Daha sonra PKCS#8 private key'ı başka bir dosyaya almak için şöyle yaparız.
openssl pkcs8 -topk8 -inform PEM -in baseKey.pem -out privateKey.pem -nocrypt
Daha sonra public key'ı başka bir dosyaya almak için şöyle yaparız.
openssl rsa -in baseKey.pem -pubout -outform PEM -out publicKey.pem  
-in seçeneği
Örnek
Private key dosyasındaki Modulus+Public Exponent değerlerini görmek için şöyle yaparız
openssl rsa -in privateKey.key -text -noout
Örnek
Sertifika dosyasındaki Modulus+Public Exponent+Private Exponent değerlerini görmek için şöyle yaparız
openssl rsa -in certificate.crt -text -noout

Örnek
pem dosyasındaki public key'i görmek için şöyle yaparız
$ openssl rsa -in my.pem  -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtrKVnwse4anfX+JzM7imShXZU
C+QBXQ11A5bOWwHFkXc4nTfEOr3fJjnRSU5A3IROFU/pVVNiXJNkl7qQZK5mYb8j
3NgqX8zZJG7IwLJ/Pm2sRW5Qj32C/uJum64Q/iEIsCg/mJjDLh1lylEMEuzKgTdW
toeLfxDBL2AJ20qXzQIDAQAB
-----END PUBLIC KEY---
-out seçeneği
PKCS#8 formatı şöyledir.
------ BEGIN PRIVATE KEY-----
[...]
-----END PRIVATE KEY-----
Geneneksel RSA formatı şöyledir.
------ BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
PKCS#8 private key'ı geleneksel RSA private key formatına çevirmek ve başka bir dosyaya almak için şöyle yaparız.
openssl rsa -in privateKey.pem -out myprivateKey.pem
-text seçeneği
Private key dosyasını görmek için şöyle yaparız
$ openssl rsa -text -in my.pem
Private-Key: (1024 bit)
modulus:
    00:ad:ac:a5:67:c2:c7:b8:6a:77:d7:f8:9c:cc:ee:
    29:92:85:76:54:0b:e4:01:5d:0d:75:03:96:ce:5b:
    01:c5:91:77:38:9d:37:c4:3a:bd:df:26:39:d1:49:
    4e:40:dc:84:4e:15:4f:e9:55:53:62:5c:93:64:97:
    ba:90:64:ae:66:61:bf:23:dc:d8:2a:5f:cc:d9:24:
    6e:c8:c0:b2:7f:3e:6d:ac:45:6e:50:8f:7d:82:fe:
    e2:6e:9b:ae:10:fe:21:08:b0:28:3f:98:98:c3:2e:
    1d:65:ca:51:0c:12:ec:ca:81:37:56:b6:87:8b:7f:
    10:c1:2f:60:09:db:4a:97:cd
publicExponent: 65537 (0x10001)
privateExponent:
(…)

6 Ekim 2019 Pazar

mmap metodu

Giriş
Şu satırı dahil ederiz.
#include <sys/mman.h>
İmzası şöyle.
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 
Bu çağrı neticesinde, yaratılan shared memory alanını, kendi uygulamamızda kullanabiliriz. mprotect ile sayfanın haklarını değiştirebiliriz.

Eğer Memory Mapped File yapmak istersek mmap ile Memory Mapped File yazısına bakabilirsiniz.

Örnek
Şöyle yaparız
mmap(
     NULL,                                /*addr*/
     321,                                 /*length*/
     PROT_EXEC | PROT_READ | PROT_WRITE,  /*prot*/
     MAP_ANONYMOUS | MAP_PRIVATE,         /*flags*/
     -1,                                  /*fd*/
     0                                    /*offset*/
)
Örnek
Şöyle yaparız. Sadece yazacağımız ve shared olan - yani diğer uygulamaların erişebileceği bir alan verir.
const int SIZE = 2048;
int  shm_fd = shm_open (...);
ftruncate (shm_fd,SIZE);
void *ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
Örnek
Şöyle yaparız. Sadece okuyacağımız ve anonim olan - yani fork() edilen uygulamarın erişebileceği - ancak private olan - yani diğer uygulamarın erişemeyeceği - bir bellek verir.
void* p = mmap(NULL, 8192,PROT_READ,MAP_ANONYMOUS|MAP_PRIVATE,-1,0);
1. Parametre - Adres
Adres parametresidir. Genelde 0 verilir.

2. Parametre  - Büyüklük
Belleğin büyüklüğünü belirtir.

3. Parametre - Haklar 
- PROT_READ : Sadece okuma hakkı verir. Bu çağrı Linux'ta aynı zamanda PROT_EXEC seçeneğinin de etkinleşmesini sağlar. Açıklaması şöyle.
Linux has an execution domain called READ_IMPLIES_EXEC, which causes all pages allocated with PROT_READ to also be given PROT_EXEC.
- PROT_WRITE :  Sadece yazma hakkı verir

4. Parametre  - flags 

MAP_POPULATE : Açıklama yaz

MAP_SHARED : Memory Mapped I/O ile IPC yapmak için bu bayrağı kullanmak gerekir

MAP_PRIVATE : Memory Mapped I/O ile IPC yapmak istenmiyorsa bu bayrağı kullanmak gerekir. Açıklaması şöyle.
MAP_PRIVATE
    ...
    It is  unspecified  whether changes made to the file
    after the mmap() call are visible in the mapped region.
MAP_ANONYMOUS :
Açıklaması şöyle.
MAP_ANONYMOUS
The mapping is not backed by any file; its contents are initialized to zero. The fd and offset arguments are ignored; however, some implementations require fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this. The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is only supported on Linux since kernel 2.4.
fork() edilen child uygulama ile belleği paylaşmamızı ancak başka uygulamaların erişememesini sağlar.
Örnek
Şöyle yaparız.
mmap(NULL, n_bytes, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
5. file descriptor
Eğer bir dosyayı belleğe yüklemek istiyorsak kullanılır. Eğer MAP_ANONYMOUS bayrağı ile kullanıyorsak -1 verilir.

Çağrı Sonucu
Bu çağrı void * döndüğü için shared memory alanı yazılacak veya okunacak veri yapısına cast edilebilir. Örnek:
struct MyStruct
{
    int s_int;
    char s_str[64];
};

void* mem = mmap ...
struct MyStruct* sp = (struct MyStruct*)mem;

/* writing */
sp->s_int = 3;
strcpy(sp->s_str, "Hello");

/* reading */
printf("s_int=%d, s_str=%s\n", sp->s_int, sp->s_str);
Ya da istersek I/O metodlarını da kullanabiliriz.
sprintf(mem, "%d", value);
mem += sizeof(value);

Unified Extensible Firmware Interface - UEFI

Giriş
Eskiden boot sector virüsleri yaygındı.

UEFI Firmware'dir
Açıklaması şöyle. Yani UEFI "EFI System Partition" da bulunan bootloader'ları bulur ve kontrolü devreder.
The motherboard contains firmware that runs bootloaders that boot OSes, and the two main types of such firmware are UEFI (new) and BIOS (old).
UEFI yerine BIOS Kullanma
Bir zararı yok. Açıklaması şöyle.
Legacy mode (a.k.a. BIOS mode, CSM boot) matters only when the operating system boots. Once it boots, it doesn't matter anymore. If everything works as expected and you're happy with it, legacy mode is fine.
Ancak UEFI kullanılması tavsiye ediliyor. Getirileri şöyle.
Advantages of UEFI boot include:

- Faster boot times. UEFI can skip initialization of some devices which would be reinitialized by OS anyway
- Optional extra security. You can enable Secure Boot, which checks digital signatures of OS components, ensuring that they weren't tampered with. You should combine it with BIOS password protection.
- If you're using multiple OSes, UEFI offers boot manager integrated into firmware.
- If you're using Windows, UEFI mode lets you use GPT partitioning scheme, which supports disks over 3 TB. (Linux can use GPT without UEFI)
UEFI ve EFI Farkı Nedir?
Açıklaması şöyle.
UEFI is an updated version of EFI after the inventors of EFI donated EFI to the UEFI (Unified EFI) forum and stopped updating EFI themselves. So, yes, UEFI is the modern EFI

UEFI Güncelleme

1. Güncellemenin Dijital İmzalı Olması Gerekir
Açıklaması şöyle. Dijital olarak imzalı güncellemeler işletim sistemi tarafından yapılabilir.
Modern computers don't have a BIOS, they have a UEFI. Updating the UEFI firmware from the running operating system is a standard procedure, so any malware which manages to get executed on the operating system with sufficient privileges could attempt to do the same. However, most UEFIs will not accept an update which isn't digitally signed by the manufacturer. That means it should not be possible to overwrite it with arbitrary code.

This, however, assumes that:

-the mainboard manufacturers manage to keep their private keys secret
-the UEFI doesn't have any unintended security vulnerabilities which allow overwriting it with arbitrary code.
2. UEFI Capsule
Açıklaması şöyle.
The most common way of updating motherboard firmware is known as "UEFI Capsule". This method is supported by Windows update, fwupd and many manufacturer applications.

UEFI Capsule firmware updates work by copying the new version of the firmware into a specified location on the EFI partition. Applying this update is NOT immediate, as UEFI becomes read-only when control is handed over to an OS. Instead, upon each boot UEFI verifies if there is an update Capsule in the specified location, validates it's signature(which would have prevented the update from being applied if the file was corrupt), and applies the update.
UEFI Variables
Açıklaması şöyle
UEFI defines variables through which an operating system can interact with the firmware. UEFI boot variables are used by the boot loader and used by the OS only for early system start-up. UEFI runtime variables allow an OS to manage certain settings of the firmware like the UEFI boot manager or managing the keys for UEFI Secure Boot protocol etc. You can get the list using:
$ efivar --list
Örnek - WSL
WSL gerçek bir sistem olmadığı için çıktı olarak şunu alırız
$ efivar --list
efivar: error listing variables: Function not implemented

UEFI System Partition Nedir
Bootloader'lar EFI system partition alanında saklanır. Açıklaması şöyle.
For UEFI there is a filesystem on the disk, (a small fat partition labeled as UEFI which contains a first stage boot loader and instructions. In some cases this is supplemented by instructions programmed into the UEFI (ie settings stored in nvram similar to the BIOS)

Once a boot loader/UEFI partition has been found, a program takes over the boot process, and this may offer the ability to boot into different modes or OSs.
Bir başka açıklama şöyle
For UEFI you typically need an EFI System Partition (sometimes referred to as ESP). It's formatted with FAT-family FS (generally FAT32) and used to store all bootloaders for all operating systems in subdirectories or a directory called EFI (EFI legacy, see?). These bootloaders are then added to boot options list in UEFI setup or by OS installers to make them selectable in UEFI's built-in boot manager.
UEFI System Partition Kalıcıdır
Açıklaması şöyle.
/boot/efi is a persistent directory that survives shutdown and reboot
Kontrol işletim sistemine devredildikten sonra bu partition'a artık gerek yok. Açıklaması şöyle
In theory neither /boot/ nor /boot/efi are commonly used after boot. The two form a bridge between the BIOS (or similar) and the operating system. They are not generally used at runtime.
UEFI System Partition FAT32 Desteği
Açıklaması şöyle.
The UEFI standard requires FAT32 support. 
Bu partition FAT32 formatındadır.
It knows about FAT32 file system (and even more file systems on non-standard implementations), therefore boot files are stored in the EFI system partition, A.K.A ESP. The UEFI loads the *.efi applications in the ESP which will then load the operating systems.
UEFI System Partition NTFS Desteği
NTFS desteklenmez. Açıklaması şöyle
UEFI doesn't support NTFS. The spec calls for FAT family support. Vendors could add NTFS support, but:

- It's not really necessary, because FAT32 is completely sufficient and much less complex
- Unless all vendors agreed to add NTFS support, it wouldn't be a universally usable configuration anyway.
GTP Nedir
GPT yine UEFI tarafından tanımlanır. GTP yazısına taşıdım

Windows BootLoader
Sanırım adresi şöyle
C:\Windows\System32\winload.efi
Ubuntu EFI Kullanıyor mu Kontrolü
Açıklaması şöyle. Örneğin benim bilgisayarım EFI kullanıyor.
/sys/firmware/efi is created every time the computer is booted.
Şöyle yaparız.
if test -d /sys/firmware/efi;then echo efi;else echo bios;fi
veya şöyle yaparız.
test -d /sys/firmware/efi && echo efi || echo bios
UEFI Ekranına Dönme
sysctl komutu kullanılır.
Örnek
Şöyle yaparız.
systemctl reboot --firmware-setup


shutdown komutu

Giriş
Linux'ta shutdown komutu seçenekler ile kullanılıyor. Ubuntu'da seçenekleri hatırlamamak için poweroff ve reboot komutları var. Bu komutlar shutdown'ı çağırır.

shutdown komutu hiç bir seçenek vermezsek 1 dakika sonra bilgisayarı kapatır. Şöyle yaparız
sudo shutdown
Eğer belli bir saatte kapatmak istersek şöyle yaparız. But durumda 11:01 de bilgisayar kapanır
shutdown 11:00
Eğer 10 dakika sonra kapatmak istersek şöyle yaparız
sudo shutdown +10
Eğer hemen kapatmak istersek şöyle yaparız
sudo shutdown now
-c seçeneği
cancel anlamına gelir.
Örnek
Beklemekte olan shutdown işlemini iptal etmek için şöyle yaparız
shutdown -c
-h seçeneği - Halt ve poweroff
Böylece init scriptlerini de çalıştırarak sistemin elektriğini keser
Örnek
Şöyle yaparız.
shutdown -h now 
Örnek
1 dakika sonra kapatmak için şöyle yaparız. Bu komutu çalıştırınca artık root hariç kimse ssh ile login olamaz.
shutdown -h +1
-H seçeneği - Sadece Halt
Peki sadece Halt Nerede Kullanılır? Ben de hep bu soruyu merak ederdim. 

1. Örneğin bilgisayarı kapatmadan bir başka kernel'i yüklemek istersek halt yaparız.
2. Sanırım esas kullanımı şöyle. Günümüzdeki masaüstü Linux için anlamlı değil ancak daha eski ve daha büyük bilgisayarlarda elektriği birden kesmiyor
Some hardware (especially larger machines such as mainframes, let alone mini computers or super computers) having the machine shutdown creates power issues with the sudden loss of power being used (not a problem on the micros/PCs most of us use as they only use a few hundred/thousand watts) thus the power off is a unwanted feature. GNU/Linux isn't just a PC OS don't forget; so power off in all cases is unwanted
Benzer bir açıklama şöyle.
halt means flush buffers, unmount drives, close all processes in a graceful way. But not power off (though some systems may power off anyway). So the hardware is still provided with power.

After halt a hard power off (pressing the power button or unplugging the power supply) will not damage the system, because it is already halted in a graceful way.
Örnek
Şöyle yaparız.
sudo shutdown -H
-P seçeneği
Açıklaması şöyle.
Requests that the system be powered off after it has been brought down.
-r seçeneği
reboot anlamına gelir.
Örnek
Şöyle yaparız.
shutdown -r now
Örnek
10 dakika sonra reboot için şöyle yaparız.
$ sudo shutdown -r +10
Shutdown scheduled for Mon 2018-09-03 18:51:13 IDT, use 'shutdown -c' to cancel.