AOSP: Android privilaged port, file group and starting service - android

I am trying to add an http server to my custom ROM, which is based on 5.1. I managed to place lighttpd binary in system/xbin via PRODUCT_COPY_FILES in device.mk, and able to run it successfully in device in eng build. Server in listening to port 80.
But in user build, server is not able to bind to 80. When checked, file owner/group is root/shell. Is this the reason port 80 is not allowed ? How to change to root/root while placing the binary ? Is there any alternative method to bind to 80 ?
EDIT-1
Another option I tried is to use iptables.. but again , permission denied.
Is there any way to add an iptable rule in android source and build ?
Also read about 'updating linux configuration' to mark port 80 as a non-privileged port.. but could not figure out how to so this.
Thanks in advance.

You should not leave it running as root on port 80. this may end up in a security breach.
Either run on a higher than 1024 port, or read this answer , especially the part that explains how to use su

Related

Add IMEI and MAC to wlan0 to Genymotion/AndroVM

Is there any way to add IMEI to AndroVM (now Genymotion) or any other Android Emulator. And also I want MAC address for wlan0 port. We already have emulators which contain MAC at lan0 port but not for wlan.
How can we do so?
if someone in your acquaintances has done so please ask them to contribute.
Details:
I am trying to build a cloud based Android App testing center as my pre final year college project for partial fulfillment towards my Bachelor of Technology (Computer Science) degree.
I am wondering how we can get more configurations for Genymotion.
Or if you can provide me with more device configurations and if it is possible to build configurations for genymotion for different devices very quickly.
Secondly, How to add MAC addresses and IMEI number to the builds?
We are trying to emulate a mobile device (non Google nexus) to make a cloud based testing centre.
For this we are trying to use androVM (Genymotion) and we are facing a few problems
What have we done so far
Building the androVm source code in "VBOX86tp-userdebug" mode from the scratch after following the steps given on official Android website.
After building the source code on a virtual ec2 server, typing the emulator command runs but its blank.
And if possible can AndroVm be run in "Fastboot" mode so that we can install it on the device.
We have been working on "building the androVm" from source code and trying to accomplish few tasks like
Running it with the img's available after the building process is complete.
Making it portable ie creating an iso/ova out of all the stuff found in the out directory.
What we have tried till now
Downloading of the AndroVm source code
initializing the repo using repo init
Downloading the source code using repo sync
choosing the lunch menu using lunch
choosing vbox86tp-userdebug
Other menus full-eng didn't work so discontinued
Few errors that came our way
Make errors: they were pretty straightforward so resolved
system.img was not being generated: resolved by making it again
bin/bash jar command error: happened to be the path error resolved by the exporting the path to jar command.
Few Questions
What an OVA file consits of and how can it be created? From what I have seen it contains few VMDK's and few configurations files attached to it,
How to convert the platform specific image files(system.img ramdisk.img userdata.img) into an OVA or ISO file.
If at all we are missing few files to give to the emulator, can you just name them.
Also how to add IMEI number
We already have MAC for eth0/1 port but we want it on wlan port
Now to make things interesting
This is the reply I got from Genymotion Team:
I want my project to cover various configurations but for starters if i can get something like Samsung Galaxy phones and tab or as a
start if I can get Samsung galaxy tab 2.
You can change the screen size and DPI for each virtual device. You
can toggle navigation bar and virtual keyboard. However, we cannot
provide virtual devices that contains proprietary applications like
Samsung.
Now here what we get is the MAC address of eth0/1 port. What if I need wlan MAC.
Unless one of the two network interface have been disabled, there
should be 2 interfaces, 2 IP, and 2 MAC addresses: adb shell ip a. 2:
eth0: mtu 1500 qdisc pfifo_fast
state UP qlen 1000
link/ether 08:00:27:d4:fe:e0 brd ff:ff:ff:ff:ff:ff
inet 192.168.56.101/24 brd 192.168.56.255 scope global eth0
inet6 fe80::a00:27ff:fed4:fee0/64 scope link
valid_lft forever preferred_lft forever 3: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:c8:37:e7 brd ff:ff:ff:ff:ff:ff
inet 10.0.3.15/24 brd 10.0.3.255 scope global eth1
inet6 fe80::a00:27ff:fec8:37e7/64 scope link .
Sorry, but we do not provide support for specific ROM. However, I
strongly recommend you to visit the community at:
https://groups.google.com/forum/#!forum/genymotion-users
1. What an OVA file consits of and how can it be created ?From what i have seen it contains few VMDK's and few configurations files
attached to it,
"The entire directory can be distributed as an OVA package, which is a
tar archive file with the OVF directory inside."
(http://en.wikipedia.org/wiki/Open_Virtualization_Format)
2. How to convert the platform specific image files(system.img ramdisk.img userdata.img) into an OVA or ISO file.
If at all we are missing few files to give to the emulator, can you just name them.
Please read the community tutorials
3. Also how to add IMEI number
There is currently no way to add IMEI number. This feature will come
in the near future
4. We already have MAC for eth0 port but we want it on wlan port
There is 2 interfaces: eth0 and eth1. Eth0 is used for Genymotion
application widgets. If this network connection is broken, Genymotion
would not be able to start anymore. Eth1 is used for network current
access (fake WiFi connection). You can change this network
configuration as you want.
It is a common practice for mobile applications to identify the user by IMSI number (associated with the SIM card) or IMEI number (unique ID of the device). Of course, it is also possible on Android:
TelehponyManager manager = (TelehponyManager)getSystemService(TELEPHONY_SERVICE);
String imei = manager.getDeviceId();
String imsi = manager.getSubscriberId();
This code works perfectly fine on a real device, however under emulator IMEI is always all-zero and it’s not configurable. It quickly becomes awkward when debugging a network-enabled application which uses IMEI as a user ID.
Trying to resolve the problem I first looked at the TelephonyManager service, just to find the following snippet:
private IPhoneSubInfo getSubscriberInfo() {
// get it each time because that process crashes a lot
return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
}
Fair comment, isn’t it? It really made my day :)
Anyway, code analysis shows that IMEI/IMSI request goes down through all the telephony layers (see the diagram), eventually getting to the baseband device. In case of emulated system, rild daemon is used together with libreference-ril.so – reference Vendor RIL library which talks to the baseband modem device using plain, old AT commands.
The modem device itself is emulated outside the Android system, as part of qemu (which is the heart of the emulator). Details of the communication between the emulator and the Android system running inside the emulator are interesting on its own (all the communication goes through a virtual serial port, Android system’s qemud daemon is used to (de)multiplex the data). I’ll try to post a brief introduction to the topic soon.
Virtual modem implementation can be found in external/qemu/telephony/android_modem.c. The most important part of the file is this function:
const char* amodem_send( AModem modem, const char* cmd );
This function is called for each received AT command. For each command sDefaultResponses array is searched for a given command and either predefined response is sent, or a command handler is executed. The array itself looks like:
static const struct {
const char* cmd; /* command coming from libreference-ril.so, if first
character is '!', then the rest is a prefix only */
const char* answer; /* default answer, NULL if needs specific handling or
if OK is good enough */
ResponseHandler handler; /* specific handler, ignored if 'answer' is not NULL,
NULL if OK is good enough */
} sDefaultResponses[] =
{
/* ... */
{ "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL }, /* request internation subscriber identification number */
{ "+CGSN", "000000000000000", NULL }, /* request model version */
/* ... */
};
Two array rows cited above are responsible for IMSI and IMEI retrieval. As you can see, both values are hardcoded and there is no chance to modify them without recompiling the emulator.
However, an old-school hack comes in handy. The emulator binary is not encrypted nor compressed, so the string literals should be visible inside the emulator binary. In fact they are, and IMEI number can be modified in a few simple steps:
** backup the emulator binary
** open the binary with your favourite hex editor
** search for +CGSN string followed by a null byte, it should be followed by 15 digits of the IMEI number
** edit the number, be careful not to change the number of digits
** save the file, that’s all!
Sure, it’s not a perfectly comfortable solution, yet better than nothing. In the next part I’ll explain how to make IMEI number a configurable option. Enjoy!

Android: Error Resolving hostname to IP

I have been doing some low-level hacking on Android.
I'm trying to enable wifi i.e. establish Internet Connectivity through terminal (adb shell). I have written a C program to achieve this by hacking into android's bionic library and libnetutils library to get things working.
Everything works fine. I'm able to acquire an IP address via dhcp request. The problem is that whenever I try to open any site for ex. google.com via browser, it does not opens. But when I enter the IP address of the site "74.125.228.66" (google.com), the page gets loaded.
I have tried several options, like modifying the dns entries in file "resolv.conf" (present in /system/etc) and in file "20-dns.conf" (in /system/etc/dhcpcd/dhcpcd-hooks).
I also tried using "setprop" call to set dns values manually for "dhcp.eth0.dns*" and "dhcp.wlan0.dns*".
But nothing seems to work. There's also an interesting behavior I noticed. If I turn on wifi manually from "settings" menu and then turn it off and then run my program, I don't face this issue anymore. Looks like it uses some settings that I could not figure out.
My guess is that this is DNS issue, but it may be something else. Let me know if anyone has faced this issue before.
Here's is what I do to enable wifi:
Enable wpa_supplicant daemon using set_prop().
Send a dhcp request to acquire IP (code from dhcpclient.c in libnetutils).
Enable dhcpcd daemon using set_prop(). (Even without this, everything works. I ran this so that IP lease gets renewed automatically. ( Although I'm not sure about this, if dhcpcd daemon would take care of lease renewal or not) ).
In order to enable WIFI on Android via command line through a C program, you'll need to do the following:
1) Enable wpa_supplicant daemon. (Make sure you have the wpa_supplicant.conf file at /data/misc/wifi with AP (access point) information in it.). wpa_supplicant internally takes care of loading the driver and then establishes connectivity to the specified networks in its configuration file based on availability and strength.
2) Issue a dhcp request. ( To fetch IP, lease, dns1, dns2 etc.)
3) Start dhcpcd daemon. (For Lease renewal)
4) Set net.dns* properties. (Without this, DNS service would not work for any application)
In order to enable daemons (wpa_supplicant and dhcpcd) and set net.dns* properties , you'll need to use Android property system (property_set() and property_get() functions). To learn more about Android Property System, follow this link:
http://rxwen.blogspot.com/2010/01/android-property-system.html
In order to use above 2 functions, you'll need to hack into bionic and core libcutils library.
Location:
/bionic/libc/bionic/system_properties.c
/system/core/libcutils/properties.c
For issuing dhcp request, you need to hack some of the implementation of libnetutils
Location:
/system/core/libnetutils/*
Disabling Wifi:
1) Unload the driver manually.
2) Stop wpa_supplicant daemon.
3) Stop dhcpcd daemon.
4) Unset net.dns* properties.
In this case, driver needs to be unloaded manually unlike loading. If this step is not done, then any of the existing connections will not be torn apart even after 2, 3, and 4. To manually unload the driver, you need to issue "DRIVER STOP" request to wpa_supplicant which will take care of interacting with kernel to unload the driver.
In order to communicate with wpa_supplicant, you'll need to hack into wpa_cli implementation to see how it works. It basically uses UNIX Domain Sockets to interact with the supplicant. You basically need to have a look at wpa_ctrl.c and wpa_cli.c
To learn more about wpa_supplicant, wpa_cli, follow below link:
http://hostap.epitest.fi/wpa_supplicant/devel/
All above that I explained to you is done in Android at HAL layer.
Location:
/hardware/libhardware_legacy/wifi/wifi.c
So, basically whenever you toggle wifi switch from settings menu, control passes from wifi_app code to wifi_frameworks layer (WifiManager and WifiServices) which passes control to wifi.c (HAL layer) through JNI implementation (WifiNative).
A good starting point would be to look at wifi.c if you want to know things that are done at low level to enable wifi.
PS - All above is what I learned after several attempts trying to figure out stuff on my own. There are no documents or blogs (atleast I didn't find any!) that would specify what needs to be done and order of events that should be followed to enable/disable WIFI. So, it may be possible you might find a better way of doing things. This worked for me, something else might work for you!

Run app as super user?

I wanted to test Unified Remote (WiFi Remote for your PC) and I wasn't able
to connect to my PC in any way (although I could ping from PC to my Android). In the instructions it said I should try a ping from my Android to the PC, so I used the Android Terminal Emulator to try a ping and it just printed this:
ping: icmp open socket: Operation not permitted
My Android is rooted so I typed su and tried again and it worked. So I figured that Unified Remote needs su-rights to open a socket and connect to the server on my PC! The only problem is, that Unified Remote doesn't ask for su-rights... (Like the terminal. It didn't want root rights until i used su and I guess the same thing happens internally with Unified Remote)
Can I somehow start an App (in this case Unified Remote) with su-rights WITHOUT having it asking???
EDIT:
So now I tried 2 other remote control apps and none of them were able to find a server (neither detect it automaticly nor manually... And yes, I have installed and opened the server!) Again -> Ping works fine.... What surprises me is that only remote control apps have that problem... For example FTP with ES File Explorer works fine... Also I have an online game wich works fine too... I don't get it :(
Android device
ping: icmp open socket: Operation not permitted
Solution:
After Root my android mobile - PING socket error occured and I solved the issue by setting "ping" file permission as given below:
Read Write Execute
Owner Y - Y - Y
Group Y - N - Y
Others Y - N - Y
------------------
Set UID: Y
Set GID:
Sticky:
------------------
Octal Value: 4755 rwsr-xr-x
-------------------------------
You can edit permission by Root Explorer android software - Found - Play Store.
If the application it self not asking you for su rights than there is NO need to do it manualy.
I checked Google Play and in description of Unified Remote I dind't find any hint that it requires su rights.

how to change port 80 android

I made a webserver on my android device(using Nanohttpd). It's working fine over the port 8080
but I want to make it okay over the port 80,(I want to tape on my browser : http://192.168.x.x instead of http://192.168.x.x:8080/ ) but I'm not able to do it
This is how I call the method that creates the webserver:
httpServer = new NanoHTTPD(80,Environment.getExternalStorageDirectory());
Can someone tell me what service is running by default over the port 80 ?
How can i fix this problem ?
I finally found a way to fix that, for those who have the same problem, here is the solution
I rooted the phone using UnlockRoot
then I installed Port redirector from the play store and I forwarded the traffic from port 80 to port 8080, and now my web server is available from the address: 192.168.x.x
Hope it will help :)
Ports below 1024 are restricted on Unix like systems. You need superuser privileges to bind to these "well-known" ports.
List of these "well-known" ports on wikipedia
Check out line 89 of the server source:
https://github.com/NanoHttpd/nanohttpd/blob/master/core/src/main/java/fi/iki/elonen/NanoHTTPD.java
I don't even see a constructor that type-matches your arguments. That might be part of the problem.

Accessing localhost:port from Android emulator

I'm running a web service on my local machine that runs at localhost:54722.
I want to call the service from an app running in the Android emulator.
I read that using 10.0.2.2 in the app would access localhost, but it doesn't seem to work with the port number as well. It says HttpResponseException: Bad Request.
You can access your host machine with the IP address "10.0.2.2".
This has been designed in this way by the Android team. So your webserver can perfectly run at localhost and from your Android app you can access it via "http://10.0.2.2:<hostport>".
If your emulator must access the internet through a proxy server, you can configure a custom HTTP proxy from the emulator's Extended controls screen. With the emulator open, click More , and then click Settings and Proxy. From here, you can define your own HTTP proxy settings.
Use 10.0.2.2 for default AVD and 10.0.3.2 for Genymotion
Since 10.0.2.2 is not a secure domain for Android you have to allow non-secured domains in your network configuration for API 28+ where non-TLS connections are prevented by default.
You may use my following configurations:
Create a new file in main/res/xml/network_security_config.xml as:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>
And point it in AndroidManifest.xml
<application
......
......
android:networkSecurityConfig="#xml/network_security_config">
I faced the same issue on Visual Studio executing an web app on IIS Express. to fix it you need to go to your project properties then click on Debug Tab and change http://localhost:[YOUR PORT] to http://127.0.0.1:[YOUR PORT] and set the android url to http://10.0.2.2:[YOUR PORT]. it worked for me.
I'm not sure this solution will work for every Android Emulator and every Android SDK version out there but running the following did the trick for me.
adb reverse tcp:54722 tcp:54722
You'll need to have your emulator up an running and then you'll be able to hit localhost:54722 inside the running emulator device successfully.
If you are using IIS Express you may need to bind to all hostnames instead of just `localhost'. Check this fine answer:
https://stackoverflow.com/a/15809698/383761
Tell IIS Express itself to bind to all ip addresses and hostnames. In your .config file (typically %userprofile%\My
Documents\IISExpress\config\applicationhost.config, or
$(solutionDir).vs\config\applicationhost.config for Visual Studio
2015), find your site's binding element, and add
<binding protocol="http" bindingInformation="*:8080:*" />
Make sure to add it as a second binding instead of modifying the existing one or VS will just re-add a new site appended with a (1) Also, you may need to run VS as an administrator.
I solved it with the installation of "Conveyor by Keyoti" in Visual Studio Professional 2015.
Conveyor generate a REMOTE address (your IP) with a port (45455) that enable external request.
Example:
Conveyor allows you test web applications from from external tablets and phones on your network or from Android emulators (without http://10.0.2.2:<hostport>)
The steps are in the following link :
https://marketplace.visualstudio.com/items?itemName=vs-publisher-1448185.ConveyorbyKeyoti
The problem is that the Android emulator maps 10.0.2.2 to 127.0.0.1, not to localhost. So configure your web server to serveron 127.0.0.1:54722 and not localhost:54722. That should do it.
After running your local host you get http://localhost:[port number]/ here you found your port number.
Then get your IP address from Command, Open your windows command and type ipconfig
In my case, IP was 192.168.10.33 so my URL will be http://192.168.10.33:[port number]/.
In Android, the studio uses this URL as your URL. And after that set your URL and your port number in manual proxy for the emulator.
I have a webserver running on my localhost.
If I open up the emulator and want to connect to my localhost I am using 192.168.x.x. This means you should use your local lan ip address. By the way, your HttpResponseException (Bad Request) doesn't mean that the host is not reachable.
Some other errors lead to this exception.
To access localhost on Android Emulator
Add the internet permission from AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
Add android:usesCleartextTraffic="true", more details here:
Run the below-mentioned command to find your system IP address:
ifconfig | grep "inet " | grep -v 127.0.0.1
Copy the IP address obtained from this step (A)
Run your backend application, which you can access at localhost or 127.0.0.1 from your sytem.
Now in android studio, you can replace the URL if you're using in code or You can use the ip address obtained from step(A) and try opening in web browser,
Like this http://192.168.0.102:8080/
Don't forget to add PORT after the IP address, in my case app was running on 8080 port so I added IP obtained in (A) with the port 8080
you need to set URL as 10.0.2.2:portNr
portNr = the given port by ASP.NET Development Server my current service is running on localhost:3229/Service.svc
so my url is 10.0.2.2:3229
i'd fixed my problem this way
i hope it helps...
"BadRequest" is an error which usually got send by the server itself, see rfc 2616
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
So you got a working connection to the server, but your request doesn't fit the expecet form. I don't know how you create the connection, what headers are included (if there are any) – but thats what you should checking for.
If you need more help about, explain what your code is about and what it uses to connect to the Server, so we have the big picture.
Here is a question with the same Problem – the answer was that the content-type wasnt set in the header.
1) Run ipconfig command in cmd
2) You will get result like this
3) Then use IPv4 Address of VMWare Network Adapter 1 followed by port number
In My Case its 8080, so instead of using localhost:8080
I am using 192.168.56.1:8080
Done.....
I would like to show you the way I access IISExpress Web APIs from my Android Emulator. I'm using Visual Studio 2015. And I call the Android Emulator from Android Studio.
All of what I need to do is adding the following line to the binding configuration in my applicationhost.config file
<binding protocol="http" bindingInformation="*:<your-port>:" />
Then I check and use the IP4 Address to access my API from Android emulator
Requirement: you must run Visual Studio as Administrator. This post gives a perfect way to do this.
For more details, please visit my post on github
Hope this helps.
For Laravel Homestead Users:
If anyone using Laravel with homestead you can access app backend using 192.168.10.10 in emulator
Still not working?
Another good solution is to use ngrok https://ngrok.com/
I am using Windows 10 as my development platform, accessing 10.0.2.2:port in my emulator is not working as expected, and the same result for other solutions in this question as well.
After several hours of digging, I found that if you add -writable-system argument to the emulator startup command, things will just work.
You have to start an emulator via command line like below:
emulator.exe -avd <emulator_name> -writable-system
Then in your emulator, you can access your API service running on host machine, using LAN IP address and binding port:
http://192.168.1.2:<port>
Hope this helps you out.
About start emulator from command line: https://developer.android.com/studio/run/emulator-commandline.
Explanation why localhost is not available from emulators for anyone who has basic access problem. For sophisticated cases read other answers.
Problem: Emulator has own local network and localhost maps itself to emulator, but NOT your host!
Solution:
Bind your server to 0.0.0.0 to make it available for emulator's network
Get external IP address of your laptop: ifconfig command for Mac
In Android (or Flutter app) use IP address of your external interface like: 192.168.1.10 instead of localhost
I had the same issue when I was trying to connect to my IIS .NET Webservice from the Android emulator.
install npm install -g iisexpress-proxy
iisexpress-proxy 53990 to 9000 to proxy IIS express port to 9000 and access port 9000 from emulator like "http://10.0.2.2:9000"
the reason seems to be by default, IIS Express doesn't allow connections from network
https://forums.asp.net/t/2125232.aspx?Bad+Request+Invalid+Hostname+when+accessing+localhost+Web+API+or+Web+App+from+across+LAN
localhost seemed to be working fine in my emulator at start and then i started getting connection refused exception
i used 127.0.2.2 from the emulator browser and it worked and when i used this in my android app in emulator it again started showing the connection refused problem.
then i did ifconfig and i used the ip 192.168.2.2 and it worked perfectly
Bad request generally means the format of the data you are sending is incorrect. May be mismatched data mapping . If you are getting bad request implies you are able to connect to the server, but the request is not being sent properly.
If anybody is still looking for this, this is how it worked for me.
You need to find the IP of your machine with respect to the device/emulator you are connected. For Emulators on of the way is by following below steps;
Go to VM Virtual box -> select connected device in the list.
Select Settings ->Network-> Find out to which network the device is attached. For me it was 'VirtualBox Host-Only Ethernet Adapter #2'.
In virtualbox go to Files->Preferences->Network->Host-Only Networks, and find out the IPv4 for the network specified in above step. (By Hovering you will get the info)
Provide this IP to access the localhost from emulator. The Port is same as you have provided while running/publishing your services.
Note #1 : Make sure you have taken care of firewalls and inbound rules.
Note #2 : Please check this IP after you restart your machine. For some reason, even If I provided "Use the following IP" The Host-Only IP got changed.
I resolved exact the problem when the service layer is using Visual Studio IIS Express. Just point to 10.0.2.2:port wont work. Instead of messing around the IIS Express as mentioned by other posts, I just put a proxy in front of the IIS Express. For example, apache or nginx. The nginx.conf will look like
# Mobile API
server {
listen 8090;
server_name default_server;
location / {
proxy_pass http://localhost:54722;
}
}
Then the android needs to points to my IP address as 192.168.x.x:8090
if you are using some 3rd party package like node express or angular-cli you will need to find the IP of your machine, and attach your host to that IP within the server startup config (instead of localhost). Then launch it from the emulator using the IP. For example, I had to use: ng serve -H 10.149.212.104 to use the angular-cli. Then from the emulator I used: http://10.149.212.104:4200
If you are working with Asp.Net Web API, in .vs/config folder inside your project, modify these lines as per you port setting. Let suppose you use port 1234 and physicalPath to the project folder set by IIS is "D:\My Projects\YourSiteName", then
<site name="YourSiteName" id="1">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="D:\My Projects\YourSiteName" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:1234:*" />
</bindings>
</site>
In android studio, access your api with "http://10.0.2.2:1234" ...

Categories

Resources