Entwickler-Ecke
Windows API - SpeedGear
SAiBOT - Fr 21.08.09 02:02
Titel: SpeedGear
Ich habe ein Tool names "SpeedGear" gefunden (
http://www.softcows.com/speed_gear.htm) mit dem es möglich ist Prozesse zu verlangsamen/beschleunigen. Das will ich nun nachbauen :P .
Erst dachte ich es seien nur API Hooks, also habe ich mich rangemacht und habe folgende Funktionen gehookt:
- timeGetTime (Winmm.dll)
- timeSetEvent (Winmm.dll)
- GetTickCount (kernel32.dll)
- QueryPerformanceCounter (kernel32.dll)
- Sleep (kernel32.dll)
- WaitForSingleObject (kernel32.dll)
- SetTimer (user32.dll)
Das funktioniert nun mit Ausnahme von wenigen Prozessen auch sehr gut!
Alle Ausnahme Prozesse mit denen ich rumprobiert habe, sind mit SpeedGear allerdings auch veränderbar!?
In der "whatsnew.txt" steht:
| Zitat: |
Version 5.0
[+] Enhanced speeder kernel arithmetic
[+] New "linearity-accelerate" technology |
In der "tips.txt" steht:
| Zitat: |
| Speed Gear only changes the CPU speed! ... |
Dann habe ich bei Google noch diesen Text gefunden:
| Zitat: |
| Speed Gear's working theory is brilliant: Speed Gear enters computer system ring 0, which is also known as Kernel Mode. Then changes the system time intermit. Once system time intermit is changed, all games' speed will be changed. For example: It cheats game thinks two seconds is only one second, so the characters in game will run twice fast. |
Weiss jemand was genaueres ?
MfG
delfiphan - Fr 21.08.09 16:41
Die Zeit wird vom Kernel ständig nachgeführt. Ich denke mal das passiert bei einem (hardware) timer interrupt. Es gibt ein Chip, der in gewissen (konfigurierbaren) Intervallen dem Prozessor einen tick gibt. Dann wird dort ein Hardware Interrupt ausgelöst. Dort wird dann z.B. der Scheduler fürs Multitasking ausgeführt, welcher dafür sorgt, dass nach dem Beenden des Interrupts die Kontrolle ggf. an den nächsten Prozess geht.
Du kannst wohl also entweder das Intervall halbieren, oder die Zeit doppelt inkrementieren. Berücksichtigen musst du vermutlich auch noch, dass es alle x Minuten eine synchronisation mit der Hardware-Uhr gibt. Die Details auszuarbeiten wird wohl nicht so ganz einfach..
SAiBOT - Fr 21.08.09 17:24
Da die Änderungen nicht global auftreten, sondern Prozess spezifisch, gehe ich davon aus, dass des Rätsels Lösung irgendwo im Prozess-Objekt steckt?
zB. in einer vergleichbaren Struktur, wie dieser hier:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| _KERNEL_USER_TIMES = record CreateTime: LARGE_INTEGER; ExitTime: LARGE_INTEGER; KernelTime: LARGE_INTEGER; UserTime: LARGE_INTEGER; end; |
Die abgefragt/geändert durch folgende Funktionen wird:
NtQueryInformationProcess/NtSetInformationProcess
:?!?:
delfiphan - Fr 21.08.09 17:31
Vielleicht reicht es ja für deine Zwecke, wenn du QueryPerformanceFrequency hookst (Edit: Ach so, das hast du schon gemacht).
Ich kann auch nur spekulieren.
SAiBOT - So 23.08.09 12:32
Mein Denkansatz war völlig falsch, dies ist der richtige Weg:
Per Treiber zB. WinIo¹ (Nur nötig ab Win2000, bis XP gibt es sogar noch API Funktionen dafür!) die I/O Ports des PIT's² ansteuert und den PIT so programmieren!
Wie genau das alles nun funktioniert... ich weiß es noch nicht :nixweiss:
Hier die I/O Ports:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| ------------------------------------------------------------------------------- 0040-005F ---- PIT (Programmable Interrupt Timer 8253, 8254) XT & AT uses 40-43 PS/2 uses 40, 42,43,44, 47
0040 r/w PIT counter 0, counter divisor (XT, AT, PS/2) 0041 r/w PIT counter 1, RAM refresh counter (XT, AT) 0042 r/w PIT counter 2, cassette & speaker (XT, AT, PS/2)
0043 r/w PIT mode port, control word register for counters 0-2 bit 7-6 = 00 counter 0 select = 01 counter 1 select (not PS/2) = 10 counter 2 select bit 5-4 = 00 counter latch command = 01 read/write counter bits 0-7 only = 10 read/write counter bits 8-15 only = 11 read/write counter bits 0-7 first, then 8-15 bit 3-1 = 000 mode 0 select = 001 mode 1 select - programmable one shot = x10 mode 2 select - rate generator = x11 mode 3 select - square wave generator = 100 mode 4 select - software triggered strobe = 101 mode 5 select - hardware triggered strobe bit 0 = 0 binary counter 16 bits = 1 BCD counter
0044 r/w PIT counter 3 (PS/2, EISA) used as fail-safe timer. generates an NMI on time out. for user generated NMI see at 0462.
0047 w PIT control word register counter 3 (PS/2, EISA) bit 7-6 = 00 counter 3 select = 01 reserved = 10 reserved = 11 reserved bit 5-4 = 00 counter latch command counter 3 = 01 read/write counter bits 0-7 only = 1x reserved bit 3-0 = 00
0048 EISA 0049 8254 timer 2, not used (counter 1) 004A EISA programmable interval timer 2 004B EISA programmable interval timer 2 ------------------------------------------------------------------------------- |
Edit: @delfiphan: Deine Vermutung traf es ziemlich genau :zustimm:
_________________
1. The WinIo library allows 32-bit Windows applications to directly access I/O ports and physical memory. It bypasses Windows protection mechanisms by using a combination of a kernel-mode device driver and several low-level programming techniques.
(
http://www.internals.com/utilities_main.htm)
2. Programmable Interrupt Timer.
(
http://toasteros.web17.webbpro.de/sites/tutorials/PIT.pdf)
(
http://www4.informatik.uni-erlangen.de/Lehre/WS07/V_BS//Uebungen/oostubs/web/aufgaben/aufgabe5/timer.shtml)
SAiBOT - Fr 28.08.09 10:10
Ok ich habs, die PIT-Technik ist veraltet, aber wer sich dafür interessiert:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74:
| #include "stdafx.h" #include "ntport.h"
#define FREE_INT_NO 5
void Ring0() { __asm { cli mov al,34h out 43h,al mov ax,bx out 40h,al mov al,ah out 40h,al sti iretd; } }
void SetClockNT(int freq) { Outport(0x43,0x34); Outport(0x40,freq&0xff); Outport(0x40,(freq>>8)&0xff); }
void SetClock9x(int freq) { union Function_Pointer { void (*pointer)(); char bytes[sizeof(void *)]; }OldIntAddress,NewIntAddress;
int IDTAddress; int IDTItemAddress; char *Pointer; __asm { push eax sidt [esp-2] pop eax mov IDTAddress,eax } IDTItemAddress=FREE_INT_NO*8+IDTAddress; Pointer=(char *)IDTItemAddress; NewIntAddress.pointer=Ring0; OldIntAddress.bytes[0]=Pointer[0]; OldIntAddress.bytes[1]=Pointer[1]; OldIntAddress.bytes[2]=Pointer[6]; OldIntAddress.bytes[3]=Pointer[7]; Pointer[0]=NewIntAddress.bytes[0]; Pointer[1]=NewIntAddress.bytes[1]; Pointer[6]=NewIntAddress.bytes[2]; Pointer[7]=NewIntAddress.bytes[3]; __asm { mov ebx,freq int FREE_INT_NO }
Pointer[0]=OldIntAddress.bytes[0]; Pointer[1]=OldIntAddress.bytes[1]; Pointer[6]=OldIntAddress.bytes[2]; Pointer[7]=OldIntAddress.bytes[3]; } |
Eleganter ist es natürlich, das ganze nicht Systemweit zu machen, dafür sind spezielle QueryPerformanceCounter/GetTickCount Hooktechniken nötig!
Vielleicht release ich bald eine SpeedGear ebenwürdige
Freeware :wave:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!