Tuesday, July 30, 2013

Foray Into Socket Programming in C++

Had to go linuxy on this one, since the Windows stuff was wonky.  Works though.  Simple server.  Gotta start somewhere!

Line 15 creates the socket, line 20 binds it and gives it my specified properties (ports/IP to listen on), and line 25 makes it listen for connections.

Line 38 is in a loop which will accept a connection from a client. 

Line 43 basically turns the socket handle into a file, to make reading and writing to it super easy.  It'll echo back the IP of the client and then close the connection.

1:  #include <stdio.h>  
2:  #include <sys/socket.h>  
3:  #include <arpa/inet.h>  
4:  #include <unistd.h>  
5:    
6:  int main()  
7:  {  
8:       int sockethandle, bindedhandle, listeninghandle;  
9:       sockaddr_in server_info;  
10:         
11:       server_info.sin_family = AF_INET;  
12:       server_info.sin_addr.s_addr = htonl(INADDR_ANY);  
13:       server_info.sin_port = htons(7777);  
14:         
15:       if((sockethandle=socket(AF_INET, SOCK_STREAM, 0))<0)  
16:       {  
17:            fprintf(stderr, "Error creating Socket.\n");  
18:       }  
19:    
20:       bindedhandle = bind(sockethandle, (sockaddr *) &server_info, sizeof(server_info));  
21:         
22:       if(bindedhandle<0)  
23:            printf("bind error");  
24:         
25:       listeninghandle = listen(sockethandle, 3);  
26:         
27:       if(listeninghandle<0)  
28:            printf("listen error");  
29:         
30:       printf("listening on port: %d\n", ntohs(server_info.sin_port));  
31:       while(1)  
32:       {  
33:            int sessionsocket;  
34:            char *ipofclient;  
35:            struct sockaddr_in client_info;  
36:            unsigned int client_info_size = sizeof(client_info);  
37:              
38:            sessionsocket=accept(sockethandle, (sockaddr *) &client_info, &client_info_size);  
39:              
40:            ipofclient=inet_ntoa(client_info.sin_addr);  
41:            printf("client %s is connected\n\n", ipofclient);  
42:              
43:            FILE *read=fdopen(sessionsocket, "r");  
44:            FILE *write=fdopen(sessionsocket, "w");  
45:              
46:            fprintf(write, "GREETS, %s!\n", ipofclient);  
47:    
48:            fflush(write);  
49:            fclose(write);  
50:            fclose(read);  
51:            close(sessionsocket);  
52:       return 0;  
53:       }  
54:  }  


Firefall Auto-Trigger Bot

Recently finished a memory-based auto-trigger for the MMO Firefall.  I blanked out some of the values because I'm hoping maybe Red5 (the company) will compensate me for the code since it's making me ungodly powerful in PvP as an Electron.  I also removed a bunch of functions that aren't used (rightclick(), sendkey() etc..)

Awesome learning experience!

Firefall sets a value in memory based on what you are aiming at.  It changes to one value for a player, another for a NPC/world object (printers, garages, etc), and is null when aiming at nothing (the ground/sky).  First I search through a chunk of memory once while aiming at an object, finding all addresses with that value. (lines 130-154).

Since there are multiple hits (usually around 20), a second loop was needed to narrow down to the right address.  After aiming at a player, it'll scan again running those previous addresses against the new expected values (lines 161-173).  The left over value is (99% of the time) the right address.

For some reason, the first 5-10 leftclick() events sent to Firefall make me aim in crazy places, so after initiating the auto-trigger, I make it shoot a few times to settle itself down (lines 183-187).

Since I'm loaning this EXE to a friend in-game to play with me, I added the function kaboom(), which when I say a phrase in-game, closes his Firefall process.  This way if we get into a match against each-other, he can't use my own tool against me :)



1:  #include <iostream>  
2:  #include <Windows.h>  
3:  #include <TlHelp32.h>  
4:  #include <tchar.h>  
5:    
6:  using namespace std;   
7:    
8:  void leftclick()  
9:  {  
10:       PINPUT click = new INPUT;  
11:       click->type = INPUT_MOUSE;  
12:       click->mi.dwFlags = 0x2;  
13:       click->mi.mouseData = 0;   
14:       click->mi.time = 0;  
15:       click->mi.dwExtraInfo = 0;  
16:       SendInput(1,click,sizeof(INPUT));  
17:       click->mi.dwFlags = 0x4;  
18:       SendInput(1,click,sizeof(INPUT));  
19:  }  
20:    
******************
******************   
115:  #define PC_BEGIN 0x**  
116:  #define PC_END 0x**  
117:  #define NPC_BEGIN 0x**  
118:  #define NPC_END 0x**  
119:    
120:  DWORD findAddy(HANDLE hHandle)  
121:  {  
122:       DWORD resultsCounter=0, bigCounter=0, goodHitsA[1000], goodHitsB[1000],betterHit=0,endCounter=0;   
123:       char y[1000], z[1000];  
124:       DWORD addy=0x00000000;  
125:       DWORD x[1000];  
126:         
127:       cout << "Aim at NPC/world object, hit enter, and wait.";  
128:       cin.get();  
129:    
130:       while(bigCounter<0x01000000)  
131:       {  
132:            ReadProcessMemory(hHandle, (LPVOID)addy, &y[0], sizeof(&y[0]), 0);  
133:            if(y[0]==NPC_BEGIN)  
134:            {  
135:                 //printf("0xPC_BEGIN at %08X\n", addy);  
136:                 for(int i=0;i<8;i++)  
137:                 {  
138:                      addy++;  
139:                      ReadProcessMemory(hHandle, (LPVOID)addy, &y[i+1], sizeof(&y[i]), 0);  
140:                      x[i]=addy-1;  
141:                 }  
142:                 //ignoreme   
143:                 if(y[0]==NPC_BEGIN&&y[7]==NPC_END)  
144:                 {  
145:                      printf("***HIT***\tx[0] = %08X\n", x[0]);  
146:                      goodHitsA[resultsCounter]=x[0];  
147:                      goodHitsB[resultsCounter]=x[7];  
148:                      resultsCounter++;  
149:                 }  
150:                 bigCounter++;  
151:            }  
152:            addy++;  
153:            bigCounter++;  
154:       }  
155:    
156:    
157:       cout << "Now aim at a player, and hit enter." << endl;  
158:       cin.get();  
159:    
160:    
161:       for(int i = 0; i < resultsCounter;i++)  
162:       {  
163:            ReadProcessMemory(hHandle, (LPVOID)goodHitsA[i], &z[i], sizeof(&goodHitsA[i]), 0);  
164:            ReadProcessMemory(hHandle, (LPVOID)goodHitsB[i], &y[i], sizeof(&goodHitsB[i]), 0);  
165:            //printf("z[0] = %08X\ty[0] = %08X\n", z[0], y[0]);  
166:            if(z[i]==PC_BEGIN&&y[i]==PC_END)  
167:            {  
168:                 betterHit=goodHitsB[i];  
169:                 cout << "Press Enter to initiate auto-trigger. GET SOME GET SOME!!!\n";  
170:                 cin.get();  
171:                 Sleep(2000);  
172:            }  
173:       }  
174:       if(!betterHit)  
175:       {  
176:            printf("Unsuccessful, best bet is to restart FireFall completely and try again.");  
177:            return 1;  
178:       }  
179:    
180:       //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  
181:       //    Clicks to stop the spazzing  
182:       //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  
183:       for (int i=0;i<10;i++)  
184:       {  
185:            leftclick();  
186:            Sleep(200);  
187:       }  
188:    
189:       return betterHit;  
190:  }  
191:    
192:  void kaboom(HANDLE hHandle)  
193:  {  
194:       int counter=0;  
195:       DWORD base=0x00000000;  
196:       char y[20];  
197:       while(counter<0x01000000)  
198:       {  
199:            ReadProcessMemory(hHandle, (LPVOID)base, &y[0], sizeof(&y[0]), 0);  
200:            if(y[0]==0x**)  
201:            {  
202:                 //printf("0x** at %08X\n", base);  
203:                 for(int i=0;i<16;i++)  
204:                 {  
205:                      base++;  
206:                      ReadProcessMemory(hHandle, (LPVOID)base, &y[i+1], sizeof(&y[i]), 0);  
207:                 }  
208:                 if(y[0]==0x**&&y[1]==0x**&&y[2]==0x**&&y[3]==0x**&&y[4]==0x**&&y[5]==0x**&&y[6]==0x**&&y[7]==0x20&&y[8]==0x6B&&y[9]==0x61&&y[10]==0x62&&y[11]==0x6F&&y[12]==0x6F&&y[13]==0x6D&&y[14]==0x21)  
209:                 {  
210:                      TerminateProcess(hHandle, 0);  
211:                 }  
212:                 counter++;  
213:            }  
214:            base++;  
215:            counter++;  
216:       }  
217:  }  
218:    
219:  int main()  
220:  {  
221:    
222:       //************************************************  
223:       //     Gets PID of FirefallClient.exe  
224:       //************************************************  
225:       HANDLE hHandle;  
226:       HANDLE hSnapshot;  
227:       PROCESSENTRY32 entry;  
228:       entry.dwSize=sizeof(entry);  
229:       hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);  
230:       if(Process32First(hSnapshot, &entry) == TRUE)  
231:       {  
232:            while(Process32Next(hSnapshot, &entry)==TRUE)  
233:            {  
234:                 if (_tcscmp(entry.szExeFile, TEXT("FirefallClient.exe"))==0)  
235:                 {  
236:                      hHandle = OpenProcess(PROCESS_VM_READ, FALSE, entry.th32ProcessID);  
237:                      break;  
238:                 }  
239:            }  
240:       }  
241:       if(!hHandle)  
242:       {  
243:            printf("OpenProcess() Failed!\n");  
244:            return 1;  
245:       }  
246:       else  
247:       {  
248:            printf("FirefallClient.exe (PID: %d) opened successfully\n", entry.th32ProcessID);  
249:       }  
250:    
251:       DWORD addy;  
252:       addy=findAddy(hHandle);  
253:       char buffer;  
254:       while(1)  
255:       {  
256:            //for(int i=0;i<300000;i++)  
257:            //{  
258:                 ReadProcessMemory(hHandle, (LPVOID)addy, &buffer, sizeof(&addy), 0);  
259:                 if(buffer!=0)  
260:                 {  
261:                      leftclick();  
262:                      Sleep(50);  
263:                 }  
264:                 Sleep(10);  
265:            //}  
266:            //kaboom(hHandle);  
267:       }  
268:  }  

At first, I had the PID hard-coded in to the program and had to re-compile each time.  Then I evolved to using a command line argument.  Finally, I stepped it up to automatically finding it out based on the executable name, which makes things super easy!  Unfortunately I had some issues comparing the text from a PROCESSENTRY32 structure with quoted text (line 234), so this took longer than it should have.  Apparently PROCESSENTRY32.szExeName is stored as a TCHAR (unicode) and quoting text makes it (const char *) so it kept bitching at me.  There's also a way to do it with a window name, but since Firefall is in debug-mode, the window title was constantly changing to show KBp/s, framerate, etc.

The next step would be somehow attaching a debugger to Firefall (it's anti-cheat has an anti-debugger in it) and finding out the exact offset so I could just have the right address every time and don't have to scan for it. Since the location in memory changes every time I run Firefall, the scanning is necessary, but being able to just run/stop it on demand would be fantastic.

Whatever.  Win!