모의 위치 비활성화 / 확인 (gps 스푸핑 방지)
Android에서 GPS 스푸핑을 방지 / 감지하는 가장 좋은 방법을 찾고 있습니다. 이 작업을 수행하는 방법에 대한 제안 사항과이를 중지하기 위해 수행 할 수있는 작업은 무엇입니까? 사용자가 GPS를 스푸핑하려면 모의 위치를 켜야한다고 생각합니다.이 작업이 완료되면 GPS를 스푸핑 할 수 있습니까?
모의 위치가 활성화되어 있는지 감지해야할까요? 다른 제안이 있습니까?
여기에서 조사하고 결과를 공유했습니다. 이것은 다른 사람들에게 유용 할 수 있습니다.
먼저 MockSetting 옵션이 켜져 있는지 확인할 수 있습니다.
public static boolean isMockSettingsON(Context context) {
// returns true if mock location enabled, false if not enabled.
if (Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
return false;
else
return true;
}
둘째, android.permission.ACCESS_MOCK_LOCATION
(위치 스푸핑 앱)을 사용하는 기기에 다른 앱이 있는지 확인할 수 있습니다.
public static boolean areThereMockPermissionApps(Context context) {
int count = 0;
PackageManager pm = context.getPackageManager();
List<ApplicationInfo> packages =
pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo applicationInfo : packages) {
try {
PackageInfo packageInfo = pm.getPackageInfo(applicationInfo.packageName,
PackageManager.GET_PERMISSIONS);
// Get Permissions
String[] requestedPermissions = packageInfo.requestedPermissions;
if (requestedPermissions != null) {
for (int i = 0; i < requestedPermissions.length; i++) {
if (requestedPermissions[i]
.equals("android.permission.ACCESS_MOCK_LOCATION")
&& !applicationInfo.packageName.equals(context.getPackageName())) {
count++;
}
}
}
} catch (NameNotFoundException e) {
Log.e("Got exception " , e.getMessage());
}
}
if (count > 0)
return true;
return false;
}
위의 방법 (첫 번째와 두 번째 방법)이 모두 사실이라면 위치가 스푸핑되거나 가짜 일 가능성이 높습니다.
이제 위치 관리자의 API를 사용하여 스푸핑을 방지 할 수 있습니다.
공급자 (네트워크 및 GPS) 모두에게 위치 업데이트를 요청하기 전에 테스트 공급자를 제거 할 수 있습니다.
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
try {
Log.d(TAG ,"Removing Test providers")
lm.removeTestProvider(LocationManager.GPS_PROVIDER);
} catch (IllegalArgumentException error) {
Log.d(TAG,"Got exception in removing test provider");
}
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);
removeTestProvider (~)가 Jelly Bean 이상 버전에서 매우 잘 작동하는 것을 보았습니다. 이 API는 Ice Cream Sandwich까지 신뢰할 수없는 것으로 보입니다.
이를 수행하는 유일한 방법은 위치 스푸핑이 MockLocation을 방지하는 것을 방지하는 것 같습니다. 단점은 더 나은 신호를 얻기 위해 Bluetooth GPS 장치를 사용하는 일부 사용자가 있다는 것입니다. 그들은 모의 위치를 사용해야하므로 앱을 사용할 수 없습니다.
이를 위해 다음을 수행했습니다.
// returns true if mock location enabled, false if not enabled.
if (Settings.Secure.getString(getContentResolver(),
Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
return false;
else return true;
API 18부터 위치 개체 에는 .isFromMockProvider () 메서드가 있으므로 가짜 위치를 필터링 할 수 있습니다.
18 이전 버전을 지원하려면 다음과 같이 사용할 수 있습니다.
boolean isMock = false;
if (android.os.Build.VERSION.SDK_INT >= 18) {
isMock = location.isFromMockProvider();
} else {
isMock = !Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0");
}
몇 년 후이 스레드를 우연히 발견했습니다. 2016 년에 대부분의 Android 기기는 API 레벨이 18 이상이므로 Fernando가 지적한대로 Location.isFromMockProvider () 에 의존해야합니다 .
다양한 Android 기기 및 배포판에서 가짜 / 모의 위치를 광범위하게 실험했습니다. 불행히도 .isFromMockProvider () 는 100 % 신뢰할 수 없습니다. 가끔 가짜 위치는 mock로 표시되지 않습니다 . 이는 Google Location API의 잘못된 내부 융합 로직 때문인 것 같습니다.
I wrote a detailed blog post about this, if you want to learn more. To summarize, if you subscribe to location updates from the Location API, then switch on a fake GPS app and print the result of each Location.toString() to the console, you will see something like this:
Notice how, in the stream of location updates, one location has the same coordinates as the others, but is not flagged as a mock and has a much poorer location accuracy.
To remedy this problem, I wrote a utility class that will reliably suppress Mock locations across all modern Android versions (API level 15 and up):
LocationAssistant - Hassle-free location updates on Android
Basically, it "distrusts" non-mock locations that are within 1km of the last known mock location and also labels them as a mock. It does this until a significant number of non-mock locations have arrived. The LocationAssistant can not only reject mock locations, but also unburdens you from most of the hassle of setting up and subscribing to location updates.
To receive only real location updates (i.e. suppress mocks), use it as follows:
public class MyActivity extends Activity implements LocationAssistant.Listener {
private LocationAssistant assistant;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// You can specify a different accuracy and interval here.
// The last parameter (allowMockLocations) must be 'false' to suppress mock locations.
assistant = new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false);
}
@Override
protected void onResume() {
super.onResume();
assistant.start();
}
@Override
protected void onPause() {
assistant.stop();
super.onPause();
}
@Override
public void onNewLocationAvailable(Location location) {
// No mock locations arriving here
}
...
}
onNewLocationAvailable()
will now only be invoked with real location info. There are some more listener methods you need to implement, but in the context of your question (how to prevent GPS spoofing) this is basically it.
Of course, with a rooted OS you can still find ways of spoofing location info that are impossible for normal apps to detect.
If you happened to know the general location of cell towers, you could check to see if the current cell tower matches the location given (within an error margin of something large, like 10 or more miles).
For example, if your app unlocks features only if the user is in a specific location (your store, for example), you could check gps as well as cell towers. Currently, no gps spoofing app also spoofs the cell towers, so you could see if someone across the country is simply trying to spoof their way into your special features (I'm thinking of the Disney Mobile Magic app, for one example).
This is how the Llama app manages location by default, since checking cell tower ids are much less battery intensive than gps. It isn't useful for very specific locations, but if home and work are several miles away, it can distinguish between the two general locations very easily.
Of course, this would require the user to have a cell signal at all. And you would have to know all the cell towers ids in the area --on all network providers-- or you would run the risk of a false negative.
try this code its very simple and usefull
public boolean isMockLocationEnabled() {
boolean isMockLocation = false;
try {
//if marshmallow
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
AppOpsManager opsManager = (AppOpsManager) getApplicationContext().getSystemService(Context.APP_OPS_SERVICE);
isMockLocation = (opsManager.checkOp(AppOpsManager.OPSTR_MOCK_LOCATION, android.os.Process.myUid(), BuildConfig.APPLICATION_ID)== AppOpsManager.MODE_ALLOWED);
} else {
// in marshmallow this will always return true
isMockLocation = !android.provider.Settings.Secure.getString(getApplicationContext().getContentResolver(), "mock_location").equals("0");
}
} catch (Exception e) {
return isMockLocation;
}
return isMockLocation;
}
This scrip is working for all version of android and i find it after many search
LocationManager locMan;
String[] mockProviders = {LocationManager.GPS_PROVIDER, LocationManager.NETWORK_PROVIDER};
try {
locMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
for (String p : mockProviders) {
if (p.contentEquals(LocationManager.GPS_PROVIDER))
locMan.addTestProvider(p, false, false, false, false, true, true, true, 1,
android.hardware.SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
else
locMan.addTestProvider(p, false, false, false, false, true, true, true, 1,
android.hardware.SensorManager.SENSOR_STATUS_ACCURACY_LOW);
locMan.setTestProviderEnabled(p, true);
locMan.setTestProviderStatus(p, android.location.LocationProvider.AVAILABLE, Bundle.EMPTY,
java.lang.System.currentTimeMillis());
}
} catch (Exception ignored) {
// here you should show dialog which is mean the mock location is not enable
}
You can add additional check based on cell tower triangulation or Wifi Access Points info using Google Maps Geolocation API
The simplest way to get info about CellTowers
final TelephonyManager telephonyManager = (TelephonyManager) appContext.getSystemService(Context.TELEPHONY_SERVICE);
String networkOperator = telephonyManager.getNetworkOperator();
int mcc = Integer.parseInt(networkOperator.substring(0, 3));
int mnc = Integer.parseInt(networkOperator.substring(3));
String operatorName = telephonyManager.getNetworkOperatorName();
final GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
int cid = cellLocation.getCid();
int lac = cellLocation.getLac();
You can compare your results with site
To get info about Wifi Access Points
final WifiManager mWifiManager = (WifiManager) appContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (mWifiManager != null && mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
// register WiFi scan results receiver
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> results = mWifiManager.getScanResults();//<-result list
}
};
appContext.registerReceiver(broadcastReceiver, filter);
// start WiFi Scan
mWifiManager.startScan();
}
참고URL : https://stackoverflow.com/questions/6880232/disable-check-for-mock-location-prevent-gps-spoofing
'programing' 카테고리의 다른 글
Android Studio에서 Jar로 라이브러리를 내보내는 방법은 무엇입니까? (0) | 2020.09.23 |
---|---|
SQL Server로 마지막 행을 읽는 방법 (0) | 2020.09.23 |
루비 문자열의 클래스 이름을 실제 클래스로 변환 (0) | 2020.09.23 |
파일 이름을 변경하면 파일의 MD5 해시에 영향을 줍니까? (0) | 2020.09.23 |
관리되는 .NET 언어로 JIT 컴파일러 (네이티브 코드로)를 작성할 수 있습니까? (0) | 2020.09.23 |