OldSchoolHack

Registrieren / Anmelden Deutsch

Daten finden CS:S


icon Daten finden CS:S #1

Anmeldungsdatum: Okt 2012

Beiträge: 14

Hallo Leute,

möchte gerne wissen, wie ich bestimmte Daten in einem Spiel (CS:S) mit OllyDbg finden kann.

1. Ich starte das Spiel (Deticated Server oder einfach lokal, ist erstmal egal).
2. Ich klinke mich in den hl2.exe ein dort wurden verschiedene DLLs geladen (engine.dll, client.dll)
3. Hier kann ich jetzt theoretisch den Stack, Heap, Code usw. ansehen

Nun zu meinem Verständnisproblem:
- Wieso haben Stack und Code einen anderen Adressbereich? Wird das im PE-Header festgelegt?
http://www.os-forum.com/minix/net/images/bh_brk_sbrk.gif müsste das nicht zusammenhängend sein?

- Wo landen im Endeffekt die Daten wie punchangle usw. und wie finde ich diese? Nach was sucht z.B. die Funktion "All referenced text strings" - im Stack, im Heap, in Funktionsnamen?

Möchte die Daten dann mit ReadProcessMemory() auslesen.

Gruß anothernewb

icon #2

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
code ist idr. die .text section, hat also einen eigenen bereich.
stack ist der stapelspeicher wo z.b. temporäre variablen, funktionsparameter etc. drauf abgelegt werden.
heap ist der dynamische speicherbereich, findest du eigtl alles auch auf google/wikipedia.

um bestimmte daten zu finden eignet sich olly eher weniger, für soetwas würde ich cheatengine benutzen.

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #3

Anmeldungsdatum: Okt 2012

Beiträge: 14

Ist mir schon klar, dass was die Sektionen machen. Nur warum hat der Stack einen anderen Adressbereich als die Code-Sektion?

Schaue mir gerade die Tutorials an, somit hat sich die Frage nach dem Finden der Adressen erstmal geklärt.
icon #4

Anmeldungsdatum: Aug 2007

Beiträge: 8643

Benutzer-Bewertung:

199 positiv
33 negativ
weil die Daten im Codebereich nichts zu suchen haben? Daten liegen vorzugsweise genau hintereinander im Speicher. Das wäre im Codebereich nicht möglich, da der bestenfalls gar keinen Platz für Daten hat.

greetz KN4CK3R

__________________

Hallo
icon #5

Anmeldungsdatum: Okt 2012

Beiträge: 14

Dachte immer, dass das Programm beim starten die Sektionen .data .bss .text nacheinander in den RAM lädt und dann an dem EntryPoint in das Programm einsteigt.
icon #6

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
achso, nein eigtl haben die auch nicht einen extra adressbereich.
alles muss in einer 32bit anwendung mit einem 32 bit pointer darstellbar sein.

aber natürlich gibt es spezielle bereiche, z.b. ist der codebereich mit bestimmten protections gesetzt, dass er z.b. als ausführbar markiert ist, während man z.b. auf dem stack idr. nur lesen und schreiben kann.

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #7

Anmeldungsdatum: Okt 2012

Beiträge: 14

Okay, ich schau mir mal die Tutorials an bin gerade beim Flashhack

Danke
icon #8

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
changes im code von spielexecutables sind vac detected!
je nachdem wie du den flashhack implementierst ist es detected, also vorsicht.

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #9

Anmeldungsdatum: Okt 2012

Beiträge: 14

Jo ich gammel lokal. Gibt es da trotzdem noch Möglichkeiten z.B. die Texturen aus dem RAM werfen oder so?
icon #10

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
sicher.
wenn du das tut von kn4ck3r befolgst findeste nen bissl weiter oben im code nen compare von 2 floats und nen ja (jump if above), wo geschaut wird ob nen flashtimer > als nen globaler timer ist.
den flashtimer immer auf 0 setzen, dann biste nie geflasht, siehe auch hier:
https://www.oldschoolhack.me/forum/counterstrike-16sourcego/8596,css-noflash,0.html

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #11

Anmeldungsdatum: Okt 2012

Beiträge: 14

Also ich habe jetzt den Breakpoint (mit F2) gesetzt, komme allerdings nicht mehr ins Spiel um die Flash zu werfen und mir dann EAX+140C anzuschauen. Habe ich ein Denkfehler? Müssten die Adressen nicht bei jedem Start anders sein, wegen ASLR usw. oder reicht es dann die Baseaddress von dem Modul (client.dll) + Adresse zu nehmen?

icon #12

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
Zitat von anothernewb
Also ich habe jetzt den Breakpoint (mit F2) gesetzt, komme allerdings nicht mehr ins Spiel um die Flash zu werfen und mir dann EAX+140C anzuschauen.
sicher, breakt ja auch direkt.
weiß jetzt nicht wo du den breakpoint gesetzt hast, aber vermutlich auf dem jumpifabove, oder kurz davor.
natürlich durchläuft der code immer, er muss ja erstmal feststellen ob der flashtimer derzeit aktiv ist.
kannst also direkt eax auslesen und musst net extra ne flash werfen.
Und wie ich schonmal gesagt habe ist CE dafür weitaus besser geeignet, besonders für anfänger.

Zitat
Müssten die Adressen nicht bei jedem Start anders sein, wegen ASLR usw. oder reicht es dann die Baseaddress von dem Modul (client.dll) + Adresse zu nehmen?
baseadd von client.dll + offset (+ offset) reicht.

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #13

Anmeldungsdatum: Okt 2012

Beiträge: 14

Mega, danke! Will mit Reverse Engineering langsam mal anfangen, kommt man doch nicht drum rum
icon #14

Anmeldungsdatum: Okt 2012

Beiträge: 14

So habe jetzt mal versucht die BaseAddress von der client.dll zu bekommen, klappt scheinbar nicht (liefert immer 0 zurück), ich tippe darauf, dass er die client.dll nur über die hl2.exe bekommt.

Was hab ich falsch gemacht?

CPP Code:
  1. #include <iostream>
  2. #include <windows.h>
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. HWND handle = NULL;
  8.  
  9. while(handle == NULL)
  10. {
  11. handle = FindWindow(NULL, "Counter-Strike Source");
  12. Sleep(100);
  13. }
  14. cout << "Counter-Strike Source wurde gefunden!" << endl;
  15.  
  16. cout << (DWORD)GetModuleHandle ("client.dll") << endl;
  17.  
  18. return 0;
  19. }
  20.  
icon #15

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
GetModuleHandle geht nur in dem zielprogramm, nicht extern.
extern musst du dich ToolHelp32 bedienen, hier ich schenk dir mal eine funktion:
TEXT Code:
  1.  
  2. #include <TlHelp32.h>
  3.  
  4. DWORD External::GetModuleBase(const DWORD ProcessId, const wchar_t* ModuleName)
  5. {
  6. HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
  7. if (!hSnap)
  8. {
  9. return 0;
  10. }
  11.  
  12. MODULEENTRY32 me;
  13. me.dwSize = sizeof(MODULEENTRY32);
  14.  
  15. DWORD dwReturn = 0;
  16.  
  17. if (Module32First(hSnap, &me))
  18. {
  19. while (Module32Next(hSnap, &me))
  20. {
  21. if (lstrcmpi(me.szModule, ModuleName) == 0)
  22. {
  23. dwReturn = (DWORD)me.modBaseAddr;
  24. break;
  25. }
  26. }
  27. }
  28. CloseHandle(hSnap);
  29. return dwReturn;
  30. }
  31.  

processid kriegst mit GetWindowThreadProcessId

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #16

Anmeldungsdatum: Okt 2012

Beiträge: 14

Juhu Copy-Paste

Hmkay, wer denkt sich bitte so lange Funktionen aus?
Also die Funktion nimmt einen "Snapshot" von einem Prozess auf und sucht darin nach allen Modulen und vergleicht diese mit dem gesuchten 'const char'.

Was soll das External bedeuten?

Die Baseadresse müsste doch bei Olly im EBP Register stehen oder?

Vielen Dank für die Hilfe

icon #17

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
Funktion ist eigtl ziemlich simpel, macht nen snapshot vom prozess und vergleicht alle geladenen modulnamen mit dem gesuchten modulnamen.
External, weils teil meiner External klasse ist, musst du weglassen.

ModulBases sind seit winxp random, musst also die funktion benutzen.
oder was meinst du mit Baseadresse?

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #18

Anmeldungsdatum: Okt 2012

Beiträge: 14

Zitat
ModulBases sind seit winxp random, musst also die funktion benutzen.
oder was meinst du mit Baseadresse?
Ich wollte herausfinden, wo ich die Base vom Modul (Die mir die Funktion gibt) im OllyDbg finde.

Muss ich die Base-Adresse MINUS die Adresse von meinem Flashtimer als Offset nehmen?
icon #19

Anmeldungsdatum: Mär 2011

Beiträge: 978

Benutzer-Bewertung:

89 positiv
6 negativ
nein, du musst einen pointer auf den flashtimer finden.
der flashtimer wird über einen pointer angesteuert, den ersten offset hast du schon im debuggen gesehen (0x140C anscheinend laut deinem post oben), rechnest also die flashadresse - 0x140C, suchst dann nach dem ergebnis mit cheatengine (4byte - da pointer) und guckst ob du i-welche grünen adressen siehst (wirst du).
dann nimmst du dir die grüne adresse, doppelklick drauf, dann siehst die wahrscheinlich client.dll + 0x??????.
dann hast du alles was du brauchst:
extern die ModuleBase lesen mit der funktion die ich dir gegeben habe, dann ModuleBase + 0x?????? mit readprocessmemory auslesen, auf das ausgelesene 0x140C draufaddieren - blubb, du hast deine flashtimeradresse wo du jetzt mit writeprocessmemory in ner schleife (mit kleinem sleep - ganz sauber wäre, dass du es ausliest und guckst ob es sich verändert hat) 0.0f reinschreiben kannst.

__________________

http://www.abload.de/img/signfj5o.png
Spoiler
Vids:
Zitate:
Spoiler

Zitat von xst
Vater KN4CK3R, der du hängst im irc, geheiligt werde dein Botnet, dein P7 v1.337 komme, die Bannwelle geschehe, wie in CS:S als auch in CS:GO, führe uns nicht in Versuchung, sondern erlöse uns von all dem c+p-Shit.
Zitat von f4gsh0t_h4x
VAC ist an,immer,überall
Zitat von gibson.w
Ich mag braune Würstchen
Zitat von irc
<SilverDeath> KN4CK3R bistn nub
<~KN4CK3R> kk
Zitat von irc
<OrkSchamane> das prob is das viele dieser eig. recht guten bücher englisch sind ...
<OrkSchamane> da habe ich's ja doppelt schwer
<~KN4CK3R> falsch
<~KN4CK3R> das prob is dass du programmieren willst ohne englisch zu können
Zitat von irc
<SilverDeath> Ich schwöre dir Dr_Pepper Ich bumms deine Mutter tot Mann!
<Dr_Pepper> danke.
<SilverDeath> bitte
Zitat von irc
<~KN4CK3R> dann liegts wenigstens an mir
<~KN4CK3R> nur noch rausfinden warum -.-
<SilverDeath> ja sicher
<SilverDeath> an wem sonst?
* You were kicked by KN4CK3R (kick)
Zitat von Dr_Pepper
ihr seit beide dumm
Tutorials:
Releases:
Gifs:
Spoiler
http://www.abload.de/img/uberesp2sgul2.gif
https://i.imgur.com/Z5VQMrV.gif
http://www.abload.de/img/minesweeperzgaef.gif
icon #20

Anmeldungsdatum: Okt 2012

Beiträge: 14

TEXT Code:
  1. CPU Disasm
  2. Address Hex dump Command Comments
  3. 16095E52 F30F1041 0C MOVSS XMM0,DWORD PTR DS:[ECX+0C]
  4. 16095E57 0F2F80 0C140000 COMISS XMM0,DWORD PTR DS:[EAX+140C]

Also es geht um die Stelle, hier wird doch der XMM0 mit *EAX+140C verglichen. An EAX+140C steht aber nur 00-00-00-00.

Auf jeden Fall habe ich zu EAX ein paar grüne Adressen mit CE gefunden, die er mir allerdings bei Doppelklick nur in die Tabelle reinläd und bei Rechtsklick -> Dissasamble in Memory Region zeigt er client.CreateInferface + 2EB97C an.