Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Linux/Unix ::  c++ Speicher nach einem Wert durchsuchen .  
Gehen Sie zu Seite Zurück  1, 2
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
seldon
Unregistrierter




Beitrag seldon Unregistrierter 05:16:48 08.01.2012   Titel:              Zitieren

AirTrake schrieb:

C/C++ Code:
        int i=1;
        int *p=&i;
        int ha;
        ha = ptrace(PTRACE_POKETEXT, 1000,p, NULL);
        printf("%d",ha);
C/C++ Code:
int i=1;
int *p=&i;
int ha;
ha = ptrace(PTRACE_POKETEXT, 1000,p, NULL);
printf("%d",ha);
C/C++ Code:
        int i=1;
        int *p=&i;
        int ha;
        ha = ptrace(PTRACE_POKETEXT, 1000,p, NULL);
        printf("%d",ha);


So giebt er -1 aus.

Das ist wenig verwunderlich.
C/C++ Code:
ha = ptrace(PTRACE_POKETEXT, 1000, p, NULL);
C/C++ Code:
ha = ptrace(PTRACE_POKETEXT, 1000, p, NULL);
C/C++ Code:
ha = ptrace(PTRACE_POKETEXT, 1000, p, NULL);

bedeutet: Schreibe NULL an Speicherstelle p im virtuellen Adressraum des Prozesses mit PID 1000. Ich weiß jetzt nicht, ob und ggf. welcher Prozess bei dir die PID 1000 hatte, als das Programm lief, und ich hege die Vermutung, dass du es versäumt hast, dich vorher an diesen anzuhängen. Was ich aber weiß, ist, dass p aus dem eigenen Adressraum genommen ist und mit ziemlicher Sicherheit keine Entsprechung in Prozess 1000 hat.

Anschauungsbeispiel mit eigens erzeugtem Kindprozess:
C/C++ Code:
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
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
#include <sys/ptrace.h>
#include
<sys/types.h>
#include
<sys/wait.h>
#include
<unistd.h>

#include
<stdio.h>

int main(void) {
  int p_toparent[2];
  pid_t pid;

  pipe(p_toparent);

  pid = fork();

  if(pid == 0) {
    /* Kindprozess */
    long n = 1000;
    long *p = &n;

    close(p_toparent[0]);

    write(p_toparent[1], &p, sizeof(p));

    /* "Synchronisation" - der Vaterprozess sollte nicht länger als eine Sekunde brauchen,
     * sich die Adresse aus der Pipe zu holen. In ernsthaften Anwendungsfällen wäre dieses
     * Vorgehen natürlich haarsträubend, aber die Arbeit, das vernünftig aufzuziehen, mache
     * ich mir hierfür nicht.
     */

    sleep(1);

    printf("C: %lx\n", n);
  } else {
    /* Elternprozess */
    long data = 0xdeadbeef; /* Der rüberzuschreibende Wert */
    long *n_child;

    close(p_toparent[1]);

    printf("P: %lx\n", data);

    /* Hier wird der Wert, den der Kindprozess in die Pipe geschrieben hat, in n_child
     * gelesen.
     * n_child ist danach die Adresse von n im virtuellen Adressraum des Kindprozesses,
     * nicht im eigenen! Dementsprechend kann n_child nicht direkt verwendet werden, sondern
     * dient lediglich als Argument für ptrace.
     */

    read(p_toparent[0], &n_child, sizeof(n_child));

    /* Dann kann man sich anhängen, darauf warten, dass das SIGSTOP bearbeitet wurde,
     * danach im Adressraum des Kindprozesses rumfuhrwerken und sich wieder abhängen.
     */

    ptrace(PTRACE_ATTACH, pid, 0, 0);
    wait(NULL);
    ptrace(PTRACE_POKEDATA, pid, n_child, data);
    ptrace(PTRACE_DETACH, pid, 0, 0);

    sleep(2);
  }

  return 0;
}
C/C++ Code:
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
#include <sys/ptrace.h>
#include
<sys/types.h>
#include
<sys/wait.h>
#include
<unistd.h>

#include
<stdio.h>

int main(void) {
int p_toparent[2];
pid_t pid;

pipe(p_toparent);

pid = fork();

if(pid == 0) {
/* Kindprozess */
long n = 1000;
long *p = &n;

close(p_toparent[0]);

write(p_toparent[1], &p, sizeof(p));

/* "Synchronisation" - der Vaterprozess sollte nicht länger als eine Sekunde brauchen,
* sich die Adresse aus der Pipe zu holen. In ernsthaften Anwendungsfällen wäre dieses
* Vorgehen natürlich haarsträubend, aber die Arbeit, das vernünftig aufzuziehen, mache
* ich mir hierfür nicht.
*/

sleep(1);

printf("C: %lx\n", n);
} else {
/* Elternprozess */
long data = 0xdeadbeef; /* Der rüberzuschreibende Wert */
long *n_child;

close(p_toparent[1]);

printf("P: %lx\n", data);

/* Hier wird der Wert, den der Kindprozess in die Pipe geschrieben hat, in n_child
* gelesen.
* n_child ist danach die Adresse von n im virtuellen Adressraum des Kindprozesses,
* nicht im eigenen! Dementsprechend kann n_child nicht direkt verwendet werden, sondern
* dient lediglich als Argument für ptrace.
*/

read(p_toparent[0], &n_child, sizeof(n_child));

/* Dann kann man sich anhängen, darauf warten, dass das SIGSTOP bearbeitet wurde,
* danach im Adressraum des Kindprozesses rumfuhrwerken und sich wieder abhängen.
*/

ptrace(PTRACE_ATTACH, pid, 0, 0);
wait(NULL);
ptrace(PTRACE_POKEDATA, pid, n_child, data);
ptrace(PTRACE_DETACH, pid, 0, 0);

sleep(2);
}

return 0;
}
C/C++ Code:
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
#include <sys/ptrace.h>
#include
<sys/types.h>
#include
<sys/wait.h>
#include
<unistd.h>

#include
<stdio.h>

int main(void) {
  int p_toparent[2];
  pid_t pid;

  pipe(p_toparent);

  pid = fork();

  if(pid == 0) {
    /* Kindprozess */
    long n = 1000;
    long *p = &n;

    close(p_toparent[0]);

    write(p_toparent[1], &p, sizeof(p));

    /* "Synchronisation" - der Vaterprozess sollte nicht länger als eine Sekunde brauchen,
     * sich die Adresse aus der Pipe zu holen. In ernsthaften Anwendungsfällen wäre dieses
     * Vorgehen natürlich haarsträubend, aber die Arbeit, das vernünftig aufzuziehen, mache
     * ich mir hierfür nicht.
     */

    sleep(1);

    printf("C: %lx\n", n);
  } else {
    /* Elternprozess */
    long data = 0xdeadbeef; /* Der rüberzuschreibende Wert */
    long *n_child;

    close(p_toparent[1]);

    printf("P: %lx\n", data);

    /* Hier wird der Wert, den der Kindprozess in die Pipe geschrieben hat, in n_child
     * gelesen.
     * n_child ist danach die Adresse von n im virtuellen Adressraum des Kindprozesses,
     * nicht im eigenen! Dementsprechend kann n_child nicht direkt verwendet werden, sondern
     * dient lediglich als Argument für ptrace.
     */

    read(p_toparent[0], &n_child, sizeof(n_child));

    /* Dann kann man sich anhängen, darauf warten, dass das SIGSTOP bearbeitet wurde,
     * danach im Adressraum des Kindprozesses rumfuhrwerken und sich wieder abhängen.
     */

    ptrace(PTRACE_ATTACH, pid, 0, 0);
    wait(NULL);
    ptrace(PTRACE_POKEDATA, pid, n_child, data);
    ptrace(PTRACE_DETACH, pid, 0, 0);

    sleep(2);
  }

  return 0;
}

Prinzipiell kann man sich auf die gleiche Weise an alle Prozesse anhängen, bei denen man die entsprechenden Rechte hat (als normaler Benutzer sind das im Zweifel die von dir selbst gestarteten); wenn der andere Prozess nicht darauf vorbereitet ist, ist es aber natürlich sehr viel schwieriger, interessante Stellen in dessen Adressraum herauszufinden.
Cho++
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2011
Beiträge: 188
Beitrag Cho++ Mitglied 13:30:14 08.01.2012   Titel:              Zitieren

Naja ich lass es dann mal mit dem Zeug. :)
Muss mir jetzt wieder eine andere Idee überlegen ..

Danke für die Antworten :live:

_________________
no risk no fun!
rüdiger
Moderator

Benutzerprofil
Anmeldungsdatum: 11.07.2001
Beiträge: 22820
Beitrag rüdiger Moderator 13:35:00 08.01.2012   Titel:              Zitieren

/dev/mem
Ethon
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.01.2011
Beiträge: 1114
Beitrag Ethon Mitglied 14:50:13 08.01.2012   Titel:              Zitieren

Häng dich mit ptrace an den Prozess, parse /proc/[PID]/maps um die Liste von allen Speicherbereichen zu bekommen, lies alle Bereiche aus /proc/[PID]/mem und suche darin nach deinem Wert.


Zuletzt bearbeitet von Ethon am 14:50:38 08.01.2012, insgesamt 1-mal bearbeitet
mfq
Unregistrierter




Beitrag mfq Unregistrierter 11:57:00 16.01.2012   Titel:              Zitieren

Der aus dem Westen ... schrieb:
Direkten Speicherzugriff gibt es nur in der System- und Treiberprogrammierung. Früher, in den Tagen von DOS und UNIX (obwohl, bei UNIX bin ich mir nicht sicher, bin mit MS-DOS aufgewachsen), da konnte ein Programm noch direkt auf die Speicherzellen im RAM zugreifen.
Virtual Memory kam in der Unix-Welt Ende der 70er Jahre unter Berkeley Unix (müsste 3BSD auf der VAX gewesen sein).

Der Rest deines (übrigens äußerst wertvollem) Beitrag trifft in der Form auch nur auf x86-Systeme richtig zu (auch wenn die beschriebenen Techniken natürlich auch anderswo Verwendung finden), das sollte man vielleicht dazu sagen.

Zur Frage des Threadstarters noch:
Unter vielen Unix-Implementierungen (unter anderem eben auch unter Linux) gibt es (wie rüdiger bereits angedeutet hat) unter /dev/mem (siehe mem(4)) eine Gerätedatei, über die man (entsprechende Rechte vorausgesetzt) die Inhalte des physikalischen Speichers auslesen und durchaus auch ändern kann, wobei letzteres natürlich recht heikel ist. Zum Rumspielen durchaus interessant, es gibt aber nur sehr wenige Klassen von Programmen, in denen diese Funktionalität tatsächlich sinnvoll verwendet werden kann.
C/C++ Forum :: Linux/Unix ::  c++ Speicher nach einem Wert durchsuchen .  
Gehen Sie zu Seite Zurück  1, 2
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.