C forritunarmál
C var búið til af Dennis Ritchie á áttunda áratugnum til að endurskrifa Unix stýrikerfið. Það þýðist beint í smalamál, sem gerir það að kjörnu tungumáli til að skilja hvað gerist í vélarkóða.
Langflest bakhönnunar verkefni eru skrifuð í C og síðan þýdd í tvíundaskrá. Til að skilja hvað bakþýðendur sýna þér þarftu að þekkja grunnatriði C.
Minnisstjórnun
(e. Memory Management)
Í C sér forritarinn sjálfur um að úthluta (e. allocate) og losa (e. free) minni. Þetta er ólíkt Python eða Java þar sem þetta gerist sjálfkrafa.
int x = 5; // [Staðvær breyta](../glossary.md#stadvaear-breyta), á [stafla](../glossary.md#stafla)
int *p = malloc(4); // Kvikt minni (e. dynamic memory), á hrúgu (e. heap)
Strengir
Strengir í C eru í raun bara fylki af bætum sem enda alltaf á \0 (núll-bæti). Þetta kallast núll-endaður strengur.
char name[] = "hello";
// Í minni: [ 'h', 'e', 'l', 'l', 'o', '\0' ]
// 0x68 0x65 0x6c 0x6c 0x6f 0x00
Ef strengur er geymdur án \0 þá vita mörg föll eins og printf og strlen ekki hvar hann endar og lesa áfram í minni þar til þau finna næsta \0 bæti. Þetta getur leitt til upplýsingaleka.
Bendlar
Bendill er breyta sem geymir vistfang í minni, ekki gildið sjálft.
int x = 42;
int *p = &x; // p geymir [vistfang](../glossary.md#vistfang) x
printf("%d", *p); // * [aftilvísun](../glossary.md#aftilvisun): sækir gildið sem p bendir á → 42
Í smalamáli eru bendlar alltaf notaðir. Þegar baksmal sýnir [rax] þýðir það "gildið á vistfanginu sem rax geymir" (sjá aftilvísun).
Algeng mynstur í CTF dæmum
Samanburðarmynstur
char input[32];
fgets(input, 32, stdin);
if (strcmp(input, "secretpassword\n") == 0) {
puts("Correct!");
}
Í rev-verkefni muntu oft sjá strcmp, strncmp, eða handvirkan samanburð bæti fyrir bæti.
Dulkóðun með XOR
char flag[] = "CTF{...}";
char key = 0x42;
for (int i = 0; i < strlen(flag); i++) {
flag[i] ^= key; // XOR hvern staf við lykilinn
}
Til að afkóða: XOR aftur með sama lykli (XOR er andhverfanlegt).
Gagnatýpur og stærðir
| Gerð | Stærð | Bilið |
|---|---|---|
char |
1 bæti | -128 til 127 |
int |
4 bæti | -2^31 til 2^31-1 |
long / long long |
8 bæti | -2^63 til 2^63-1 |
pointer |
8 bæti (64 bitar) |
Integer overflow
Ef þú leggur 1 við 0x7fffffff (hámarksgildi int) færðu neikvæða tölu. Þetta er oft notað í CTF dæmum til að komast framhjá prófum.