Jaki język do programowania systemowego?

1

Potrzebny mi język do programowania sieciowego, inżynierii wstecznej oraz do programowania systemowego pod GNU/Linuksa i OpenBSD. Jaki język nadaje się lepiej do tego celu, C czy C++?

1

Rust. :)

A wybór pomiędzy C i C++ zależy od tego, jaki to system -- w C++ masz więcej możliwości (o ile umiesz z nich skorzystać), ale w POSIXie wszystko jest w C, więc C wystarczy.

1

Radzę zacząć od C. Nadaje się do opanowania podstaw programowania systemowego. Do tego całe api Linuxa (podobnie jak jądro) napisane jest w C.

Co do inżynierii wstecznej to będzie potrzebny assembler x86_64 oraz GDB. GDB jest bardzo proste, kilka filmików na YT wyjaśni że nie ma się czego bać. Warto też poznać narzędzia strace i ltrace (od system i library tracing). Radzę unikać jak ognia składni AT&T, ucz się assemblera i GDB ze składnią intela. Jako assembler polecam nasm.

Pośród osób zajmujących się security dużą popularnością cieszy się Python. Wiele narzędzi napisanych jest właśnie w tym języku. Warto się zapoznać jako lżejsza i przyjemniejsza alternatywa do C, która ma jednak z C bardzo dobrą integrację.

Na koniec zostawmy sobie GUI, QT jest w C++. W GTK nigdy nie pisałem więc się nie wypowiem, poza tym że jest dobry wrapper na GTK dla Pythona.

Na koniec, Linux == shell, kurs basha również jest nieodzowny. Polecam sprawdzić OverTheWire lub jak ktoś tu niedawno polecał LinuxJourney.

0

Pod kątem nauki programowania asystemowego: C. Niektóre elementy C++ czy STL powodują, że kod wynikowy jest trochę inny, niż w C. Np. manglowanie nazw.

#include <iostream>

using namespace std;

void funkcja(int a, int b) {
	cout << a << " + " << b << (a+b) << endl;
}

int main(int argc, char const *argv[]) {

	cout << "Hello world!" << endl;

	funkcja(55, 1);
	return 0;
}

	.file	"dupa.cpp"
	.text
	.section	.rodata
	.type	_ZStL19piecewise_construct, @object
	.size	_ZStL19piecewise_construct, 1
_ZStL19piecewise_construct:
	.zero	1
	.local	_ZStL8__ioinit
	.comm	_ZStL8__ioinit,1,1
.LC0:
	.string	" + "
	.text
	.globl	_Z7funkcjaii
	.type	_Z7funkcjaii, @function
_Z7funkcjaii:
.LFB1518:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	%edi, -4(%rbp)
	movl	%esi, -8(%rbp)
	movl	-4(%rbp), %eax
	movl	%eax, %esi
	leaq	_ZSt4cout(%rip), %rdi
	call	_ZNSolsEi@PLT
	leaq	.LC0(%rip), %rsi
	movq	%rax, %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	movq	%rax, %rdx
	movl	-8(%rbp), %eax
	movl	%eax, %esi
	movq	%rdx, %rdi
	call	_ZNSolsEi@PLT
	movq	%rax, %rcx
	movl	-4(%rbp), %edx
	movl	-8(%rbp), %eax
	addl	%edx, %eax
	movl	%eax, %esi
	movq	%rcx, %rdi
	call	_ZNSolsEi@PLT
	movq	%rax, %rdx
	movq	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rax
	movq	%rax, %rsi
	movq	%rdx, %rdi
	call	_ZNSolsEPFRSoS_E@PLT
	nop
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE1518:
	.size	_Z7funkcjaii, .-_Z7funkcjaii
	.section	.rodata
.LC1:
	.string	"Hello world!"
	.text
	.globl	main
	.type	main, @function
main:
.LFB1519:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	%edi, -4(%rbp)
	movq	%rsi, -16(%rbp)
	leaq	.LC1(%rip), %rsi
	leaq	_ZSt4cout(%rip), %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	movq	%rax, %rdx
	movq	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rax
	movq	%rax, %rsi
	movq	%rdx, %rdi
	call	_ZNSolsEPFRSoS_E@PLT
	movl	$1, %esi
	movl	$55, %edi
	call	_Z7funkcjaii
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE1519:
	.size	main, .-main
	.type	_Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB2008:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	%edi, -4(%rbp)
	movl	%esi, -8(%rbp)
	cmpl	$1, -4(%rbp)
	jne	.L6
	cmpl	$65535, -8(%rbp)
	jne	.L6
	leaq	_ZStL8__ioinit(%rip), %rdi
	call	_ZNSt8ios_base4InitC1Ev@PLT
	leaq	__dso_handle(%rip), %rdx
	leaq	_ZStL8__ioinit(%rip), %rsi
	movq	_ZNSt8ios_base4InitD1Ev@GOTPCREL(%rip), %rax
	movq	%rax, %rdi
	call	__cxa_atexit@PLT
.L6:
	nop
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE2008:
	.size	_Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
	.type	_GLOBAL__sub_I__Z7funkcjaii, @function
_GLOBAL__sub_I__Z7funkcjaii:
.LFB2009:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	$65535, %esi
	movl	$1, %edi
	call	_Z41__static_initialization_and_destruction_0ii
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE2009:
	.size	_GLOBAL__sub_I__Z7funkcjaii, .-_GLOBAL__sub_I__Z7funkcjaii
	.section	.init_array,"aw"
	.align 8
	.quad	_GLOBAL__sub_I__Z7funkcjaii
	.hidden	__dso_handle
	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
	.section	.note.GNU-stack,"",@progbits

Taki sam kod dla C:

#include <stdio.h>

void funkcja(int a, int b) {
	printf("%d + %d = %d\n", a, b, a + b);
}

int main(int argc, char const *argv[]) {
	printf("Hello world!\n");

	funkcja(55, 1);
	return 0;
}

	.file	"kucyk.c"
	.text
	.section	.rodata
.LC0:
	.string	"%d + %d = %d\n"
	.text
	.globl	_Z7funkcjaii
	.type	_Z7funkcjaii, @function
_Z7funkcjaii:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	%edi, -4(%rbp)
	movl	%esi, -8(%rbp)
	movl	-4(%rbp), %edx
	movl	-8(%rbp), %eax
	leal	(%rdx,%rax), %ecx
	movl	-8(%rbp), %edx
	movl	-4(%rbp), %eax
	movl	%eax, %esi
	leaq	.LC0(%rip), %rdi
	movl	$0, %eax
	call	printf@PLT
	nop
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	_Z7funkcjaii, .-_Z7funkcjaii
	.section	.rodata
.LC1:
	.string	"Hello world!"
	.text
	.globl	main
	.type	main, @function
main:
.LFB1:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	%edi, -4(%rbp)
	movq	%rsi, -16(%rbp)
	leaq	.LC1(%rip), %rdi
	call	puts@PLT
	movl	$1, %esi
	movl	$55, %edi
	call	_Z7funkcjaii
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE1:
	.size	main, .-main
	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
	.section	.note.GNU-stack,"",@progbits

Różnicę widać gołym okiem. Żeby poznać podstawy POSIX C wystarczy. Poza tym kiedyś struktury zadeklarowane w nagłówkach .h musiały być poprzedzane słowem struct (typedef struct {} Struktura to nie jest najlepszy pomysł) nawet w plikach .cpp a funkcje z zakresu globalnego operatorem ::. To rodziło trochę niuansów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1