Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   Unit zur VM detection + Testprogramm (https://www.delphipraxis.net/100150-unit-zur-vm-detection-testprogramm.html)

Zacherl 23. Sep 2007 13:54


Unit zur VM detection + Testprogramm
 
Hey,

zusammen mit blackdrake habe ich eine Unit entwickelt die sehr zuverlässig erkennen kann, ob das eigene Programm auf einer virtuellen Maschiene ausgeführt wird. Dabei sind sogar Fingerprints möglich, die eine Identifizierung der verschiedenen Emulations Software zulässt.

Delphi-Quellcode:
type
  TVMFingerprint = (fpUnknown, fpVMWare, fpVirtualPC, fpVirtualBox, fpNative,
    fpWINE, fpParallelsWorkstation, fpQEMU);

type
  TxDTEntry = record
    GDTBase: DWord;
    IDTBase: DWord;
    LDTRBase: DWord;
    GDTLimit: Word;
    IDTLimit: Word;
  end;

type
  TxDTArray = array of TxDTEntry;
  TFingerprintArray = array of TVMFingerprint;

// Prüft auf eine VM, wobei angegeben werden kann, ob WinE als VM gehandhabt werden soll
function IsVirtualMachine(const DetectWINE: Boolean = true): Boolean;
// Gibt einen Fingerprint anhand eines TxDTEntrys zurück
function GetVMFingerprint(xDTEntry: TxDTEntry): TVMFingerPrint; overload;
// Gibt einen Fingerprint für eine CPU zurück
function GetVMFingerprint(CPU: Cardinal): TVMFingerPrint; overload;
// Konvertiert einen Fingerprint in einen String
function VMFingerprintToStr(FP: TVMFingerprint): String;
// Gibt einen TxDTEntry für eine CPU zurück
function GetxDTEntry(CPU: Cardinal): TxDTEntry;
// Gibt ein Array of TxDTEntry für alle CPUs zurück
function GetxDTArray(var Output: TxDTArray): Integer;
// Gibt ein Array of TVMFingerprint für alle CPUs zurück
function GetFingerprintArray(var Output: TFingerprintArray): Integer;
Das ganze Funktioniert über verschiedene Tabellen, die für jede CPU existieren. Die GDT, die IDT und die LDT. Anhand deren Base Adressen und ihrer Größe (Limits) werden die VMs ermittelt.

Unterstützte Betriebssysteme:
* Win95 .. WinME
* WinNT .. WinVista

Unterstützt werden momentan:
* VirtualPC, VMWare, VirtualBox, ParallelsWorkstation und WinE.
* QEMU (Testphase)

Geplante Features:
* Sandbox detection

Download: www.viathinksoft.de/download.php?id=125

Im Archiv findet sich die Unit, der Source für das Testprogramm und eine Excel Tabelle mit unseren Messergebnissen. Wir würden uns über Feedback und weitere Messergebnisse freuen!

Gruß Zacherl

MagicAndre1981 23. Sep 2007 16:49

Re: Unit zur VM detection + Testprogramm
 
Liste der Anhänge anzeigen (Anzahl: 1)
danke, deine Unit erkennt auch auch VMs die unter Parallels Workstation laufen. Nur als Typ steht VirtualBox da.

Hier das Ergebnis (siehe Anhang) von deinem Testprogramm innerhalb einer Windows Server 2008 VM.

blackdrake 23. Sep 2007 17:01

Re: Unit zur VM detection + Testprogramm
 
Hallo.

Danke für den Beitrag. Hier wäre die Vermutung nahe, dass Parallels Workstation stets die LDTR-Base 0xDEADFF5B verwendet (Beispiel: Microsoft Virtual PC 2007 verwendet immer 0xDEADFFA8). Hast du auf Parallels Workstation noch ein anderes Betriebssystem, damit die 0xDEADFF5B-Theorie bestätigt werden kann?

Gruß
blackdrake

Zacherl 23. Sep 2007 17:19

Re: Unit zur VM detection + Testprogramm
 
(Hui, unter Parallel Workstations hatten wir bisher gar keine Testergebnisse. Bisher haben wir für VirtualBox als Erkennungsmerkmal nur das GDT Limit.

Bei Parallel Workstations scheint ja auch noch die LDTR Base anders zu sein. Da bräuchten wir allerdings mehr Messwerte. Hast du zufällig noch andere Systeme auf Parallel Workstations installiert?) - zu spät.

Habe die Unit schonmal so angepasst, dass unter VirtualBox die LDTR der Nativen LDTR des Entsprechenden Systems entspricht. Die Ausgabe dürfte dann für Parallel Workstations "Unknown" sein.

[Edit: Parallels Workstation wird nun auch erkannt. (BETA!)]

Neue Funktionen:
Delphi-Quellcode:
// Gibt ein Array of TxDTEntry für alle CPUs zurück
function GetxDTArray(var Output: TxDTArray): Integer;
// Gibt ein Array of TVMFingerprint für alle CPUs zurück
function GetFingerprintArray(var Output: TFingerprintArray): Integer;

MagicAndre1981 23. Sep 2007 20:46

Re: Unit zur VM detection + Testprogramm
 
ich installiere gleich mal ein XP. Das Ergebnis gibts dann morgen.

Zacherl 23. Sep 2007 21:03

Re: Unit zur VM detection + Testprogramm
 
Danke dir :)

MagicAndre1981 24. Sep 2007 05:53

Re: Unit zur VM detection + Testprogramm
 
Liste der Anhänge anzeigen (Anzahl: 1)
hier das Ergebnis für XP unter Parallels-


ich werde auch noch ein Win9x installieren und dann die Werte posten.

Zacherl 24. Sep 2007 11:39

Re: Unit zur VM detection + Testprogramm
 
Damit bestätigt sich unsere Annahme zumindest für NT Systeme schonmal :) Ein Win9x Test wäre sehr nett von dir ..

freak4fun 24. Sep 2007 20:18

Re: Unit zur VM detection + Testprogramm
 
Laptop in VM:
Code:
System Info
-----------
        Win Type : WinNT
        CPU count: 1

Processor # 1
-------------
        GDT : 0xFFC07000 <16687>
        IDT : 0xFFC18000 < 2047>
        LDTR: 0xDEAD4060 <WinNT>
        Type: VMWare


This application is [probably] running IN a virtual machine!
und ohne:

Code:
System Info
-----------
        Win Type : WinNT
        CPU count: 2

Processor # 1
-------------
        GDT : 0x81F3F000 < 1023>
        IDT : 0x81F3F400 < 2047>
        LDTR: 0xDEAD0000 <WinNT>
        Type: Native

Processor # 2
-------------
        GDT : 0x82A48560 < 1023>
        IDT : 0x82A48960 < 2047>
        LDTR: 0xDEAD0000 <WinNT>
        Type: Native


This application is [probably] NOT running in a virtual machine!
Ich weiß ja, dass man immer alles sofort will. :zwinker:

blackdrake 24. Sep 2007 20:25

Re: Unit zur VM detection + Testprogramm
 
Hallo freak4fun.

Vielen Dank für die Ergebnisse! :-D Unser Erkennungsmuster scheint bei VMWare mittlerweile sehr zuverlässig zu sein. Kann ich von Windows XP bei den Systemen ausgehen?

Gruß
blackdrake

freak4fun 24. Sep 2007 20:37

Re: Unit zur VM detection + Testprogramm
 
System auf Laptop unter dem der VMServer läuft ist WinVista. In der VM läuft XP. :) [Siehe Link in PN an mich]

MagicAndre1981 24. Sep 2007 21:00

Re: Unit zur VM detection + Testprogramm
 
Zitat:

Zitat von Zacherl
Ein Win9x Test wäre sehr nett von dir ..

das hatte ich mir schon gedacht und hab es probiert. Aber die Installation von WinME bleibt bei 10% hängen. Ich probier dann nochmal Win98 oder Win95.

Zacherl 24. Sep 2007 21:11

Re: Unit zur VM detection + Testprogramm
 
Okey, danke für deine Mühe :) Bei VirtualBox funktioniert leider der Monitor Treiber von Win98 nicht, so dass ich damit auch nicht testen kann =/

MagicAndre1981 25. Sep 2007 00:00

Re: Unit zur VM detection + Testprogramm
 
Liste der Anhänge anzeigen (Anzahl: 1)
so hier gibts das Ergebnis doch noch. Musste es einfach eine Weile laufen lassen, dann ging das Setup von ME doch noch.

Zacherl 25. Sep 2007 08:37

Re: Unit zur VM detection + Testprogramm
 
Danke dir recht herzlich :) Scheint zu funktionieren die Parallels Detection.

MagicAndre1981 25. Sep 2007 11:35

Re: Unit zur VM detection + Testprogramm
 
ok, wie siehts mit QEMU aus? Das müsst ihr auch noch einbauen.

Zacherl 25. Sep 2007 13:55

Re: Unit zur VM detection + Testprogramm
 
Kannte ich gar nicht :D Habs mir mal angesehen .. ist das nur für Linux Systeme? Also kann das nur auf Linux Hosts installiert werden?

Oder hat jemand diese VM parat, der bereit währe ein Paar Tests durchzuführen?

[Edit: Ah geht wohle auf Windows, allerdings ist es nicht kompatibel zu VirtualBoxs Images. Hat Jemand VMWare und könnte das kurz testen. Hier gibt es QEMU als Zip Archiv vollkommen ohne Installation. In der BAT muss man nur den Pfad zum VMWare Image angeben. http://www.zdnet.de/downloads/prg/8/...8Y_is-wc.html]

freak4fun 25. Sep 2007 15:42

Re: Unit zur VM detection + Testprogramm
 
Ich gucks mir mal an ...

Edit: Bekomme das auf die schnelle nicht mit meiner VM zum Laufen. :(

Zacherl 25. Sep 2007 16:25

Re: Unit zur VM detection + Testprogramm
 
Das ist nett :)

GuenterS 25. Sep 2007 17:29

Re: Unit zur VM detection + Testprogramm
 
Qemu gibts eigentlich auch für Windows so weit ich weiß.

Zacherl 25. Sep 2007 18:10

Re: Unit zur VM detection + Testprogramm
 
Ja klar .. das gibts für Windows, allerdings sind meine Images von VirtualBox nicht damit kompatibel. Ich meine gelesen zu haben, dass VMWare und VPC Images damit emuliert werden können.

blackdrake 26. Sep 2007 09:40

Re: Unit zur VM detection + Testprogramm
 
Oh je... ich hab mir "QEMU on Windows" (sollte es nicht "for Windows" heißen?) heruntergeladen und verstehe die 3 enthaltenen Konsolenprogramme irgendwie nicht... ich will eine GUI :cry:. Ich hab einige Virtual-PC-Images, weiß aber nicht, wie ich die nun mit QEMU aufmachen kann.

MagicAndre1981 26. Sep 2007 10:33

Re: Unit zur VM detection + Testprogramm
 
für QEMU gibts doch eine GUI. Nur ist QEMU unter Windows total lahm.

// edit: hier gibts die GUI: http://www.davereyn.co.uk/download.htm

blackdrake 26. Sep 2007 20:28

Re: Unit zur VM detection + Testprogramm
 
Ahh!!! Ich werde wahnsinnig mit diesem QEMU! :x

Meine VPC-Images kann ich nicht schreibbar öffnen, weswegen ME, 2000 und 98 mit einer Schutzverletzung abstürzen.

Nur Windows 95 kann ich mit QEMU starten:

Delphi-Quellcode:
System Info
-----------

Win Type : Win 9x
CPU count: 1

Processor #1
------------

GDT : 0xC005C374 (503)
IDT : 0x800A2000 (767)
LDTR: 0xDEAD00D0 (Win9x)
Type: Unknown

VM-Detektion: Positiv
Offenbar ist die LDTR-Erkennungssequenz für QEMU 0xDEAD00D0. Wir bräuchten aber mehr Tests, um ganz sicher zu sein.

Gruß
blackdrake

PS: Habe ich schonmal erwähnt, dass ich Linux nicht mag?

MagicAndre1981 26. Sep 2007 22:23

Re: Unit zur VM detection + Testprogramm
 
Zitat:

Zitat von blackdrake
Ahh!!! Ich werde wahnsinnig mit diesem QEMU! :x

geht mir auch so. Unter Windows ist es lahm und Linux will ich nicht extra installieren, nur um das zu testen. Aber hier gibts doch etliche Linuxer, die sollten das doch testen können.

Zacherl 26. Sep 2007 22:32

Re: Unit zur VM detection + Testprogramm
 
Hast du ne Idee, warum blackdrakes VPC2007 Images zwar erkannt werden, aber als "nicht beschreibbar" gehandhabt werden? Es können partu keine Daten geschrieben werden .. nur lesen geht.

MagicAndre1981 26. Sep 2007 22:53

Re: Unit zur VM detection + Testprogramm
 
ne sorry. :oops: Ich hab QEMU bei version 0.7 das letzte Mal angeschaut. kA, wass da jetzt bei Version 0.9 so alles (nicht) geht.

DevidEspenschied 14. Aug 2009 12:11

Re: Unit zur VM detection + Testprogramm
 
Ich muss dieses Thema nochmal eröffnen, da ein aktuelles Virtual PC 2007 als Native erkannt wird. Hier sind die Daten des Testprogramms direkt aus Virtual PC 2007:

System Info
-----------
Version : Microsoft Windows XP Professional
Win9x : No
CPU count: 1

Processor # 1
-------------
GDT : 0x8003F000 < 1023>
IDT : 0x8003F400 < 2047>
LDTR: 0xDEAD0000 <WinNT>
Type: Native

This application is [probably] NOT running in a virtual machine!


Seltsamerweise sind die Werte auf dem Wirtssystem identisch, was ich nun garnicht verstehen kann:

System Info
-----------
Version : Microsoft Windows XP Professional
Win9x : No
CPU count: 8

Processor # 1
-------------
GDT : 0x8003F000 < 1023>
IDT : 0x8003F400 < 2047>
LDTR: 0xDEAD0000 <WinNT>
Type: Native

This application is [probably] NOT running in a virtual machine!

Hat jemand eine Lösung hierfür bzw. lebt dieses Projekt eigentlich noch ?

blackdrake 14. Aug 2009 14:52

Re: Unit zur VM detection + Testprogramm
 
Wir hatten desöfteren solche Einsendungen, bei denen Benutzer angegeben hatten, dass sie in der Tat eine VM verwendeten. In so fern ist das nicht der einzige Fall.

Bezüglich MS VPC 2007 dachten wir eigentlich, dass wir dies erkennen könnten. Kann es sein, dass in einer Minor-Version etwas geändert wurde?

Das Problem ist natürlich, dass eine VM ja gerade das Ziel hat, mit allen mitteln zu versuchen, sich selbst Werte eines nativen Systems zu geben und daher ist eine solche allgemeingültige Lösung nicht so einfach.

Bei einer VM hatte ich sogar mal die Idee, die Registry auszulesen, da die Hardwarekomponenten den Namen der VM trugen. Es war aber einfach zu hardgecoded und zu ungewiss, dachte ich mir und habe ies dann nicht implementiert.

Wenn uns neue Ideen einfallen würden, würden wir das Projekt in so fern schoneinmal wieder neu erweitern und eine neue Version rausbringen.

Neutral General 14. Aug 2009 15:15

Re: Unit zur VM detection + Testprogramm
 
Hi,

Hab mir jetzt nur mal den Code angeguckt ohne ihn zu testen. Von daher kann ich nicht viel dazu sagen aber ne kleine Sache am Rande:

Ich finde folgendes Record

Delphi-Quellcode:
TxDT = record
  Limit,
  BaseLow,
  BaseHigh: Word;
end;
und auch die Funktionen wie z.B. GetIDTLimit etwas irreführend..

Die Begriffe "Base" und "Limit" klingen eher nach Attributen eines GDT-Eintrags als das was es wirklich ist. Auch wenns etwas kleinlich ist... Da ich erstmal einen Moment verwirrt auf den Code gestarrt habe bevor ich wusste was gemeint ist würde ich doch eher die Begriffe "Size" und "Offset" vorschlagen ;)

Und warum habt ihr BaseLow und BaseHigh als 2 einzelne Variablen deklariert? ein

Delphi-Quellcode:
Base: Cardinal; // bzw Offset: Cardinal
wäre kürzer und man müsste nicht rumshiften :stupid:

:mrgreen:

blackdrake 14. Aug 2009 15:49

Re: Unit zur VM detection + Testprogramm
 
Für Verbesserungen sind wir gerne offen. Ich persönlich hab mich nicht um den Assembler-Kram damals gekümmert. Vielleicht weiß ja Zacherl, wieso das so ist. Du kannst gerne mal ein Update des Code posten.

Neutral General 14. Aug 2009 16:26

Re: Unit zur VM detection + Testprogramm
 
Hi,

Ist ja nicht viel.. und eigentlich Größtenteils nur Kosmetik:

Alles aus der Unit VMDetection.pas

1)
Delphi-Quellcode:
type
  TxDTEntry = record
    GDTBase: DWord;
    IDTBase: DWord;
    LDTRBase: DWord;
    GDTLimit: Word;
    IDTLimit: Word;
  end;

// ==>

// Code natürlich entsprechend der neuen Namen anpassen
TxDTEntry = record
    GDTOffset: DWord;
    IDTOffset: DWord;
    LDTROffset: DWord;
    GDTSize: Word;
    IDTSize: Word;
  end;
2)
Delphi-Quellcode:
type
  TxDT = record
    Limit,
    BaseLow,
    BaseHigh: Word;
  end;

// ==>

TxDT = packed record // packed würde ich bei solchen Sachen empfehlen!
    Size: Word;
    Offset: DWord;
  end;
3)
Delphi-Quellcode:
function GetIDTBase: DWord;
var
  IDT: TxDT;
begin
  asm
    SIDT IDT
  end;
  Result := (IDT.BaseHigh shl 16) or IDT.BaseLow;
end;

// ===>

function GetIDTOffset: DWord;
var
  IDT: TxDT;
begin
  asm
    SIDT IDT
  end;
  Result := IDT.Offset;
end;
4)

Delphi-Quellcode:
function GetIDTLimit: DWord;

// ==>

function GetIDTSize: DWord;
5)

Delphi-Quellcode:
function GetGDTBase: DWord;
var
  GDT: TxDT;
begin
  asm
    SGDT GDT
  end;
  Result := (GDT.BaseHigh shl 16) or GDT.BaseLow;
end;

// ==>

function GetGDTOffset: DWord;
var
  GDT: TxDT;
begin
  asm
    SGDT GDT
  end;
  Result := GDT.Offset;
end;
6)
Delphi-Quellcode:
function GetGDTLimit: DWord;

// ==>

function GetGDTSize: DWord;
7)

Delphi-Quellcode:
function GetLDTRBase: DWord;

// ==>

function GetLDTROffset: DWord;
Das sind wie du siehst und ich gesagt habe ja keine wirklichen großen Änderungen^^ Hab ja gesagt dass es etwas kleinlich ist, aber so finde ich den Code schöner bzw. verständlicher.

Gruß
Neutral General

himitsu 14. Aug 2009 16:51

Re: Unit zur VM detection + Testprogramm
 
Delphi-Quellcode:
Result := (IDT.BaseHigh shl 16) or IDT.BaseLow;
und mann kann auch froh sein, daß der Compiler die Berechnung auf seine Prozessorauflösung (32 bit) hochoptimiert,
denn (Word shl 16) ergibt ja eigentlich 0, da alle Bits aus dem Word rausgeschoben würden
und die Erweiterung auf LongWord, für die Zuweisung an diesen Typ, eigentlich erst am Ende der Berechnung durchgeführt wird.

mit 32 Bit-Werten und 64 Bit als Ergebnis ginge soetwas nicht.

DevidEspenschied 15. Aug 2009 09:56

Re: Unit zur VM detection + Testprogramm
 
Vielleicht tragen die hier genannten Verbesserungen ja zur Optimierung des bestehenden Codes bei.

Grundsätzlich ist das Vergleichen von einzelnen Adressen aber immer problematisch, da es die konsequente Pflege dieses Datenbestandes voraussetzt.

Von daher müsste man sich eigentlich von den wichtigsten virtuellen Umgebungen (Heise hatte da vor kurzem mal einen Vergleichstest) die API's besorgen, da ich mir jeweils unterschiedliche Wege vorstelle, wie eine VM erkannt werden kann.

Neutral General 15. Aug 2009 11:41

Re: Unit zur VM detection + Testprogramm
 
Zitat:

Zitat von devidespe
Vielleicht tragen die hier genannten Verbesserungen ja zur Optimierung des bestehenden Codes bei.

Grundsätzlich ist das Vergleichen von einzelnen Adressen aber immer problematisch, da es die konsequente Pflege dieses Datenbestandes voraussetzt.

Von daher müsste man sich eigentlich von den wichtigsten virtuellen Umgebungen (Heise hatte da vor kurzem mal einen Vergleichstest) die API's besorgen, da ich mir jeweils unterschiedliche Wege vorstelle, wie eine VM erkannt werden kann.

Ich denke in diesem Fall macht das nichts. Die GDT/IDT sollte eigentlich IMMER an der gleichen Stelle gespeichert sein. Alles andere würde mich wundern.

DevidEspenschied 15. Aug 2009 13:31

Re: Unit zur VM detection + Testprogramm
 
Die Frage ist ja, ob die hier genannten Verbesserungsvorschläge insbesondere von Neutral General und Himitsu helfen, das bei mir nicht erkannte Virtual PC 2007 erkennbar zu machen ?

Falls ich da noch was testen soll, bin ich gerne bereit.

juergen 15. Aug 2009 15:44

Re: Unit zur VM detection + Testprogramm
 
Hallo zusammen,
gut ich nutze Windows 7 RC1 in der 64 Bit Version und als VM das komplett neue "Windows Virtual PC" (von welchem ich im übrigen sehr begeistert bin).
Zuvor hat MS ja Virtual PC xxxx verwendet.
Mit dem anscheinend völlig neuen VM geht MS neue Wege.

Die Unit erkennt diese neue VM von MS natürlich noch nicht.
(wird von Euch auch nicht supportet, noch nicht :zwinker: ; weder Windows 7 noch Windows Virtual PC)

Da diese VM von MS IMHO wohl bald weit verbreitet sein wird, allzumal man ja eine XP-Lizenz kostenfrei dazu bekommt, USB verfügbar ist, Anwendungen aus der VM wie eine normale Anwendung gestartet werden können u.v.m., wäre es doch sinnvoll dieses hier mit aufzunehmen, oder?

Ich wäre gern bereit Euch die fehlenden Informationen zu liefern bzw. auch Test's durchzuführen.
Allerdings müsste ich genau wissen was zu tun ist weil ich mich in diesem Bereich nicht auskenne.

Hisoka 8. Jul 2010 13:16

AW: Unit zur VM detection + Testprogramm
 
Mal eine kleine Frage: Wie versuchst du WINE zu erkennen? Denn da WINE keine Virtualisierungslösung ist, sollte es nicht möglich sein WINE von WinXX zu unterscheiden(von der Erkennung her). (Es wird bei mir auch nicht Unterschieden)

himitsu 8. Jul 2010 16:46

AW: Unit zur VM detection + Testprogramm
 
Zitat:

Zitat von Hisoka (Beitrag 1034273)
Wie versuchst du WINE zu erkennen?

Wine hat nicht für alles eine Umleitung, man muß also nur schauen, ob etwas "fehlt".

Hisoka 10. Jul 2010 17:40

AW: Unit zur VM detection + Testprogramm
 
Zitat:

Zitat von himitsu (Beitrag 1034328)
Zitat:

Zitat von Hisoka (Beitrag 1034273)
Wie versuchst du WINE zu erkennen?

Wine hat nicht für alles eine Umleitung, man muß also nur schauen, ob etwas "fehlt".

Das ist mal eine eher schlechte Idee. Denn dann kann man nie sicher sein wie lange der Code funktioniert. Denn die Wine Leute versuchen ja immer wieder Funktionen fertigzustellen oder neue Sachen zu implementieren. Auch gibt es dann wieder einen Unterschied zwischen einem Stub der schon mal generiert wurde und einer Funktion die noch gar nicht implementiert wurde. (Aber allgemein halte ich eher wenig von der Idee WINE erkennen zu wollen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:00 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz