Bonjour,
AVERTISSEMENT: il y a beaucoup de code:?. Si vous n'avez pas le temps de trop regarder, ce serait sympa de me dire à quoi peut-être du un seg fault dans une app multithreadée :D, je me débroullerai avec ça.
POUR CEUX QUI ONT DU TEMPS:
Je suis entrain de faire une application capable de crypter/décrypter des messages par courbe elliptique. On m'a conseillé aussi de faire un crackeur par force brute pour montrer que cette méthode de cryptage est par son concept sûre.
J'ai fait une classe User<T> représentant une personne souhaitant pouvoir envoyer des messages cryptés à un autre User qui le décryptera. J'ai fait une classe Cracker<T> (nom très recherché :mrgreen:) dérivée de User<T> qui elle intercepte les messages des users et tente de les décrypter (le pauvre ne sait pas que c'est dur et long:aie:)...
Le crackeur cherche à trouver une clé secrète d'un des deux user qu'il surveille. Pour ce faire je le dote de 4 threads suplémentaires (je pourrais ajouter des centaines de threads si j'avais une machine avec assez de cores et de processeurs8-))pour l'aider à trouver plus vite.
Sauf que mon code plante lamentablement sur un seg fault dès que j'ajoute un crackeur.
J'ai essayé d'ajouter des blocages/déblocages de mutex un peu partout dans le code qui accède à des membres et je fait des copies de ceux-ci. Mais ça plante toujours.
J'ai jamais réellement touché aux threads avant ce projet donc je sais pas quoi faire. Le debugueur de VS ne m'est pas super utile en plus (il me repère juste le seg fault mais ne me dit pas quel appel l'a provoqué dans quel thread).
J'ai fait mes propres classes de thread et de mutex (c'est un impératif) donc le problème vient peut-être de là...
Mon code:
ZThread.hpp
ZThread.cppCode:
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 #ifndef ZTHREAD_HPP_INCLUDED #define ZTHREAD_HPP_INCLUDED #include <windows.h> unsigned __stdcall launcherfunc(void* data); class ZThread { friend unsigned __stdcall launcherfunc(void* data); public: ZThread(); ZThread(void* (*ptrFunc)(void*),void* data=NULL); virtual ~ZThread(); void Start(); void Wait(); void Terminate(); bool IsRunning(){return m_isRunning;} void* GetReturnedValue(){return m_returnedValue;} protected: virtual void* Run(); HANDLE m_handle; unsigned m_id; void* m_data; void* (*m_ptrFunc)(void*); bool m_isRunning; void* m_returnedValue; }; #endif // ZTHREAD_HPP_INCLUDED
ZMutex.hppCode:
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 #include "ZThread.hpp" #include <process.h> #include <iostream> unsigned __stdcall launcherfunc(void* data) { ZThread* tmpInstance=static_cast<ZThread*>(data); tmpInstance->m_isRunning=true; tmpInstance->m_returnedValue=tmpInstance->Run(); tmpInstance->m_isRunning=false; _endthreadex(0); return 0; } ZThread::ZThread(): m_handle(NULL), m_ptrFunc(NULL), m_data(NULL), m_isRunning(false), m_returnedValue(NULL) { } ZThread::ZThread(void* (*ptrFunc)(void*), void* data): m_handle(NULL), m_ptrFunc(ptrFunc), m_data(data), m_isRunning(false), m_returnedValue() { } ZThread::~ZThread() { if(m_isRunning) Wait(); } void* ZThread::Run() { if(m_ptrFunc!=NULL) return m_ptrFunc(m_data); return (void*) 0; } void ZThread::Start() { m_handle=(HANDLE)_beginthreadex(NULL,0,&launcherfunc,this, 0,&m_id); if(m_handle==NULL) throw("Unable to create a new thread"); } void ZThread::Wait() { if(m_isRunning) { WaitForSingleObject(m_handle,INFINITE); CloseHandle(m_handle); m_handle=NULL; } }
ZMutex.cppCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #ifndef ZMUTEX_HPP_INCLUDED #define ZMUTEX_HPP_INCLUDED #include <windows.h> class ZMutex { public: ZMutex(); ~ZMutex(); void Lock(); void UnLock(); bool IsLocked(){return m_isLocked;} protected: CRITICAL_SECTION m_mutex; bool m_isLocked; }; #endif // ZMUTEX_HPP_INCLUDED
User.hppCode:
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 #include "ZMutex.hpp" ZMutex::ZMutex(): m_isLocked(false) { InitializeCriticalSection(&m_mutex); } ZMutex::~ZMutex() { DeleteCriticalSection(&m_mutex); } void ZMutex::Lock() { if(!m_isLocked) { m_isLocked=true; EnterCriticalSection(&m_mutex); } } void ZMutex::UnLock() { if(m_isLocked) { LeaveCriticalSection(&m_mutex); m_isLocked=false; } }
Cracker.hppCode:
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 #ifndef USER_HPP_INCLUDED #define USER_HPP_INCLUDED #include <cstdlib> #include <iostream> #include <string> #include <vector> #include <map> #include "ZMutex.hpp" #include "EllipticCurveUT.hpp" template<typename T> class Connection { public: Connection(){} Connection(std::multimap<char, std::pair<T,T> > correspondanceTable, EllipticCurve<T> curve,std::pair<T,T> refPoint): m_correspondanceTable(correspondanceTable), m_curve(curve), m_refPoint(refPoint) {} std::multimap<char, std::pair<T,T> > m_correspondanceTable; EllipticCurve<T> m_curve; std::pair<T,T> m_refPoint; std::pair<T,T> m_firstPoint; std::pair<T,T> m_secondPoint; }; template<typename T> class User { public: User() { m_key = 1;//c'est pour voir si le crackage marche } static void EstablishConnection(User* firstUser, User* secondUser, std::multimap<char, std::pair<T,T> > correspondanceTable, EllipticCurve<T> curve, std::pair<T,T> refPoint) { firstUser->EstablishConnection(secondUser, correspondanceTable, curve, refPoint); secondUser->EstablishConnection(firstUser, correspondanceTable, curve, refPoint); firstUser->EstablishConnection(secondUser, correspondanceTable, curve, refPoint, true); secondUser->EstablishConnection(firstUser, correspondanceTable, curve, refPoint, true); } void EstablishConnection(User* beConnectedTo, std::multimap<char, std::pair<T,T> > correspondanceTable, EllipticCurve<T> curve, std::pair<T,T> refPoint, bool secondPart = false) { m_mutex.Lock(); if(!secondPart){ m_connections[beConnectedTo] = Connection<T>(correspondanceTable, curve, refPoint); m_connections[beConnectedTo].m_firstPoint = curve.QuickExponentiation(m_key, refPoint); }if(secondPart){ m_connections[beConnectedTo].m_secondPoint = m_connections[beConnectedTo].m_curve.QuickExponentiation(m_key, beConnectedTo->GetComputedPoint(this)); } m_mutex.UnLock(); } Connection<T> GetConnection(User* user){m_mutex.Lock(); return m_connections[user]; m_mutex.UnLock();} std::pair<T,T> GetComputedPoint(User* connectedTo){m_mutex.Lock(); return m_connections[connectedTo].m_firstPoint; m_mutex.UnLock();} std::vector<std::pair<T,T> > CryptMessage(User* receiver, std::string message) { m_mutex.Lock(); std::vector<std::pair<T,T> > cryptedMessage; cryptedMessage.push_back(m_connections[receiver].m_firstPoint); std::multimap<char, std::pair<T,T> > correspondanceTable = m_connections[receiver].m_correspondanceTable; m_mutex.UnLock(); typename std::multimap<char, std::pair<T,T> >::iterator iter; for(unsigned int i =0; i < message.length(); i++) { iter = correspondanceTable.find(message[i]); if( iter != correspondanceTable.end()) { m_mutex.Lock(); cryptedMessage.push_back(m_connections[receiver].m_curve.AddPoints(m_connections[receiver].m_secondPoint, iter->second)); m_mutex.UnLock(); } //!TODO: gérer le cas où le caractère est absent de la table } return cryptedMessage; } std::string DecryptMessage(User* sender, std::vector<std::pair<T,T> > message) { std::string decryptedMessage; m_mutex.Lock(); std::multimap<char, std::pair<T,T> > correspondanceTable = m_connections[sender].m_correspondanceTable; m_mutex.UnLock(); typename std::multimap<char, std::pair<T,T> >::iterator iter; std::pair<T,T> decryptedPoint; for(unsigned int i = 0; i < message.size(); i++) { m_mutex.Lock(); decryptedPoint = m_connections[sender].m_curve.SoustractPoints(message[i], m_connections[sender].m_secondPoint); m_mutex.UnLock(); for(iter = correspondanceTable.begin(); iter != correspondanceTable.end(); iter++) { if(iter->second == decryptedPoint) { char car[2]; car[0] = iter->first; car[1] = '\0'; decryptedMessage = decryptedMessage + car; break; } } } return decryptedMessage; } void sendMessage(User* receiver, std::string message) { sendCryptedMessage(receiver, CryptMessage(receiver, message)); } void sendCryptedMessage(User* receiver, std::vector<std::pair<T,T> > cryptedMessage) { receiver->receiveCryptedMessage(this, cryptedMessage); } void receiveCryptedMessage(User* sender, std::vector<std::pair<T,T> > cryptedMessage) { std::cout<<"Received message :"<<DecryptMessage(sender, cryptedMessage)<<std::endl; } std::map<User*, Connection<T> > m_connections; static ZMutex m_mutex; protected: long long m_key; }; template<typename T> ZMutex User<T>::m_mutex; #endif // USER_HPP_INCLUDED
voilà.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 #ifndef CRACKER_HPP_INCLUDED #define CRACKER_HPP_INCLUDED #include <iostream> #include "User.hpp" #include "ZMutex.hpp" #include "ZThread.hpp" template<typename T> class Cracker; template<typename T> class InfoPackage { public: InfoPackage(){} InfoPackage(Cracker<T>* cracker, User<T>* user, User<T>* connectedUser, int offset, int iterateBy): m_cracker(cracker), m_user(user), m_connectedUser(connectedUser), m_offset(offset), m_iterateBy(iterateBy) {} InfoPackage(const InfoPackage<T>& rhs) { m_cracker = rhs.m_cracker; m_user = rhs.m_user; m_connectedUser = rhs.m_connectedUser; m_offset = m_offset; m_iterateBy = rhs.m_iterateBy; } Cracker<T>* m_cracker; User<T>* m_user; User<T>* m_connectedUser; int m_offset; int m_iterateBy; }; template<typename T> void* CrackKey(void* infos) { InfoPackage<T> informations = *(static_cast<InfoPackage<T>*>(infos)); Cracker<T>* cracker = informations.m_cracker; cracker->m_mutex.Lock(); std::pair<T,T> point = cracker->m_connections[informations.m_user].m_refPoint; std::pair<T,T> researchedPoint = informations.m_user->GetComputedPoint(informations.m_connectedUser); EllipticCurve<T> curve = cracker->m_connections[informations.m_user].m_curve; cracker->m_mutex.UnLock(); for(long long i = informations.m_offset + 1;; i+= informations.m_iterateBy) { cracker->m_mutex.Lock(); if(cracker->keyA != 0) break; if(curve.QuickExponentiation(i, point) == researchedPoint) { cracker->keyA = i; std::cout<<"KeyA found: "<<i<<std::endl; break; } cracker->m_mutex.UnLock(); } cracker->m_mutex.UnLock(); return (void*)1; } template<typename T> class Cracker: public User<T> { public: Cracker(): keyA(0), keyB(0) { } void EstablishConnection(User<T>* firstUser, User<T>* secondUser) { this->m_connections[firstUser] = firstUser->GetConnection(secondUser); CrackKeys(firstUser, secondUser); } void CrackKeys(User<T>* firstUser, User<T>* secondUser) { InfoPackage<T> infos(this, firstUser, secondUser, 0, 4); firstThread = new ZThread(&CrackKey<T>, (void*)&infos); firstThread->Start(); infos.m_offset = 1; secondThread = new ZThread(&CrackKey<T>, (void*)&infos); secondThread->Start(); infos.m_offset = 2; thirdThread = new ZThread(&CrackKey<T>, (void*)&infos); thirdThread->Start(); infos.m_offset = 3; fourthThread = new ZThread(&CrackKey<T>, (void*)&infos); fourthThread->Start(); } std::string DecryptMessage(User<T>* sender, std::vector<std::pair<T,T> > message) { } void Wait() { firstThread->Wait(); secondThread->Wait(); thirdThread->Wait(); fourthThread->Wait(); } long long keyA; long long keyB; protected: ZThread* firstThread; ZThread* secondThread; ZThread* thirdThread; ZThread* fourthThread; };
Merci pour votre aide.