flasher implement(50%)

This commit is contained in:
dxl
2020-03-11 18:53:51 +08:00
parent 57c887dc54
commit cb26672da8
18 changed files with 308 additions and 395 deletions
+1 -1
View File
@@ -109,7 +109,7 @@
<activity android:name=".activities.connect.PN53XUsbBulkTransferActivity" />
<activity android:name=".activities.tools.DumpListActivity" />
<activity android:name=".activities.tools.KeyFileListActivity" />
<activity android:name=".activities.main.FlasherMainActivity" />
<activity android:name=".activities.main.PM3FlasherMainActivity" />
</application>
Binary file not shown.
Binary file not shown.
@@ -43,7 +43,7 @@ public class AppMain extends BaseActivity {
gotoFragment(appMainDevicesFragment);
startActivity(new Intent(context, FlasherMainActivity.class));
startActivity(new Intent(context, PM3FlasherMainActivity.class));
finish();
}
@@ -1,150 +0,0 @@
package cn.rrg.rdv.activities.main;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.Nullable;
import com.proxgrind.pm3flasher.Proxmark3Flasher;
import cn.dxl.com.Com;
import cn.dxl.common.util.LogUtils;
import cn.dxl.common.widget.ToastUtil;
import cn.rrg.com.ContextCallback;
import cn.rrg.com.DevCallback;
import cn.rrg.com.UsbSerialControl;
import cn.rrg.devices.EmptyDeivce;
import cn.rrg.rdv.R;
public class FlasherMainActivity extends BaseActivity {
private UsbSerialControl control = UsbSerialControl.get();
private Proxmark3Flasher flasher = Proxmark3Flasher.getFlasher();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_pm3_flasher);
Com.initCom(control, new EmptyDeivce());
control.setContextCallback(new ContextCallback() {
@Override
public Context getContext() {
return context;
}
});
control.register(this, new DevCallback<String>() {
@Override
public void onAttach(String dev) {
}
@Override
public void onDetach(String dev) {
flasher.closeProxmark3();
}
});
findViewById(R.id.btnStatusCheck).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
flasher.isBootloaderMode();
}
}).start();
}
});
findViewById(R.id.btnClientClose).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
flasher.closeProxmark3();
}
}).start();
}
});
findViewById(R.id.btnClientOpen).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
flasher.openProxmark3();
}
}).start();
}
});
findViewById(R.id.btnDeviceConnect).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
if (control.connect(null)) {
ToastUtil.show(context, "连接成功", false);
} else {
ToastUtil.show(context, "连接失败", false);
}
}
}).start();
}
});
findViewById(R.id.btnFlashStart).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
String bootrom = "/storage/emulated/0/Download/bootrom.elf";
String fullimg = "/storage/emulated/0/Download/fullimage.elf";
if (!flasher.isPM3Opened()) {
if (!flasher.openProxmark3()) {
LogUtils.d("PM3打开失败!");
return;
} else {
LogUtils.d("PM3打开成功!");
}
}
// 如果没有在Bootloader模式下,我们需要先重启设备使其进入Bootloader模式下!
if (flasher.isBootloaderMode()) {
LogUtils.d("当前处于Bootloader模式下,将会开始刷机!");
if (flasher.flashBootRom(bootrom)) {
LogUtils.d("PM3刷写BootRom成功!");
} else {
LogUtils.d("PM3刷写BootRom失败!");
}
if (flasher.flashFullImg(fullimg)) {
LogUtils.d("PM3刷写BootRom成功!");
} else {
LogUtils.d("PM3刷写BootRom失败!");
}
flasher.flashModeClose();
flasher.closeProxmark3();
} else {
if (!flasher.enterBootloader()) {
LogUtils.d("PM3进入刷写模式失败!");
}
}
}
}).start();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
control.unregister(this);
}
}
@@ -0,0 +1,193 @@
package cn.rrg.rdv.activities.main;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.proxgrind.pm3flasher.Proxmark3Flasher;
import cn.dxl.com.Com;
import cn.dxl.common.util.LogUtils;
import cn.dxl.common.widget.ToastUtil;
import cn.rrg.com.DevCallback;
import cn.rrg.com.UsbSerialControl;
import cn.rrg.devices.EmptyDeivce;
import cn.rrg.rdv.R;
import cn.rrg.rdv.util.Paths;
public class PM3FlasherMainActivity extends BaseActivity implements DevCallback<String> {
private enum MODE {
BOOT, OS
}
private UsbSerialControl control = UsbSerialControl.get();
private Proxmark3Flasher flasher = Proxmark3Flasher.getFlasher();
private AlertDialog usbConnectWaitDialog;
//在程序执行读卡,写卡操作时的程序后台交互性提醒对话框
private AlertDialog mDialogWorkingState = null;
private Button btnFlash;
private volatile boolean startLabel = false;
private MODE mode = MODE.BOOT;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_pm3_flasher);
// init and try to connect.
control.register(this, this);
Com.initCom(control, new EmptyDeivce());
initViews();
initActions();
if (!control.connect(null)) {
usbConnectWaitDialog.show();
}
}
private void initViews() {
usbConnectWaitDialog = new AlertDialog.Builder(context, R.style.CustomerDialogStyle)
.setView(View.inflate(context, R.layout.item_usb_device_connecting, null))
.create();
usbConnectWaitDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
ImageView imgUsbConnect = usbConnectWaitDialog.findViewById(R.id.imgUsbConnect);
Glide.with(context).load(R.drawable.usb_connect).into(imgUsbConnect);
}
});
usbConnectWaitDialog.setCancelable(false);
mDialogWorkingState = new AlertDialog.Builder(context).create();
View _workingStateMsgView = View.inflate(context, R.layout.dialog_working_msg, null);
mDialogWorkingState.setView(_workingStateMsgView);
mDialogWorkingState.setTitle(R.string.tips);
mDialogWorkingState.setCancelable(false);
btnFlash = findViewById(R.id.btnFlash);
}
private void initActions() {
btnFlash.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btnFlash.setEnabled(false);
startLabel = true;
mode = MODE.BOOT;
if (control.connect(null)) {
flashDefaultFW();
} else {
ToastUtil.show(context, getString(R.string.tips_device_no_found), false);
usbConnectWaitDialog.show();
}
}
});
}
private void showWorkingDialog() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mDialogWorkingState.show();
}
});
}
private void dissmissWorkingDialog() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mDialogWorkingState.dismiss();
}
});
}
private void flashDefaultFW() {
new Thread(new Runnable() {
@Override
public void run() {
if (!flasher.isPM3Opened()) {
if (!flasher.openProxmark3()) {
LogUtils.d("PM3打开失败!");
return;
} else {
LogUtils.d("PM3打开成功!");
}
}
LogUtils.d("开始刷机!");
showWorkingDialog();
// 如果没有在Bootloader模式下,我们需要先重启设备使其进入Bootloader模式下!
if (flasher.isBootloaderMode()) {
LogUtils.d("当前处于Bootloader模式下,将会开始刷机!");
switch (mode) {
case BOOT:
if (flasher.flashBootRom(Paths.PM3_IMAGE_BOOT_FILE)) {
LogUtils.d("PM3刷写BootRom成功!");
} else {
LogUtils.d("PM3刷写BootRom失败!");
}
finishFlash();
// 开启下一轮!
mode = MODE.OS;
break;
case OS:
if (flasher.flashFullImg(Paths.PM3_IMAGE_OS_FILE)) {
LogUtils.d("PM3刷写BootRom成功!");
} else {
LogUtils.d("PM3刷写BootRom失败!");
}
finishFlash();
startLabel = false;
ToastUtil.show(context, getString(R.string.finish), false);
break;
}
dissmissWorkingDialog();
} else {
if (!flasher.enterBootloader()) {
LogUtils.d("PM3进入刷写模式失败!");
}
}
dissmissWorkingDialog();
}
}).start();
}
private void finishFlash() {
flasher.flashModeClose();
flasher.closeProxmark3();
}
@Override
protected void onDestroy() {
super.onDestroy();
control.unregister(this);
usbConnectWaitDialog.dismiss();
}
@Override
public void onAttach(String dev) {
// 自动连接设备!
control.connect(dev);
usbConnectWaitDialog.dismiss();
if (startLabel) {
flashDefaultFW();
}
}
@Override
public void onDetach(String dev) {
flasher.closeProxmark3();
usbConnectWaitDialog.show();
}
}
@@ -18,10 +18,8 @@ import cn.dxl.common.util.DiskKVUtil;
public class InitUtil {
//短称路径
public static final String LOG_TAG = InitUtil.class.getSimpleName();
//初始化dump文件目录
public static void initApplicationResource(Context context) {
AssetsUtil au = new AssetsUtil(context);
File dump_dir = new File(Paths.DUMP_DIRECTORY);
@@ -74,11 +72,13 @@ public class InitUtil {
if (!pm3_dir.mkdirs()) {
Log.d(LOG_TAG, "init pm3 dir fail!");
} else {
initProxmark3RDV4ImageFile(au);
initEasyButtonFile(au);
initPM3ForwardFile();
initHardnestedFile(au);
}
} else {
initProxmark3RDV4ImageFile(au);
initEasyButtonFile(au);
initPM3ForwardFile();
initHardnestedFile(au);
@@ -99,17 +99,23 @@ public class InitUtil {
}
}
private static void initProxmark3RDV4ImageFile(AssetsUtil au) {
//初始化标准输入的文件!
File boot = new File(Paths.PM3_IMAGE_BOOT_FILE);
File os = new File(Paths.PM3_IMAGE_OS_FILE);
au.moveFile(Paths.PM3_BOOT_FILE_NAME, boot.getAbsolutePath());
au.moveFile(Paths.PM3_OS_FILE_NAME, os.getAbsolutePath());
}
private static void initMfInfoMapsFile(AssetsUtil au) {
File f1 = new File(Paths.COMMON_DIRECTORY + "/" + "template_mifare_info_en.html");
File f2 = new File(Paths.COMMON_DIRECTORY + "/" + "template_tag_info_en.html");
//移动两个标签信息HTML文件到指定目录!
if (/*!f1.exists()*/true)
au.moveFile("template_mifare_info_en.html",
new File(Paths.COMMON_DIRECTORY + "/" + "template_mifare_info_en.html").getAbsolutePath());
if (/*!f2.exists()*/true)
au.moveFile("template_tag_info_en.html",
new File(Paths.COMMON_DIRECTORY + "/" + "template_tag_info_en.html").getAbsolutePath());
au.moveFile("template_mifare_info_en.html",
new File(Paths.COMMON_DIRECTORY + "/" + "template_mifare_info_en.html").getAbsolutePath());
au.moveFile("template_tag_info_en.html",
new File(Paths.COMMON_DIRECTORY + "/" + "template_tag_info_en.html").getAbsolutePath());
}
private static void initDumpFile(AssetsUtil au) {
@@ -230,7 +236,6 @@ public class InitUtil {
}
}
//进行日志记录开始!
public static void startLogcat(boolean open) {
//拼接名字
String name = "log.txt";
@@ -257,7 +262,6 @@ public class InitUtil {
}
}
//初始化必须要的设置!
public static void initSettings() throws IOException {
File dir = new File(Paths.SETTINGS_DIRECTORY);
if (dir.exists()) {
@@ -269,7 +273,6 @@ public class InitUtil {
}
}
//私有初始化函数!
private static void initSets() throws IOException {
File file = new File(Paths.SETTINGS_FILE);
if (!file.exists())
@@ -4,7 +4,6 @@ import android.os.Environment;
public interface Paths {
//常用的相对路径文件夹 | 文件名定义!
String EXTERNAL_STORAGE_DIRECTORY = Environment.getExternalStorageDirectory().getPath();
String TOOLS_PATH = "NfcTools";
String SETTINGS_PATH = "Settings";
@@ -26,7 +25,6 @@ public interface Paths {
String DEFAULT_DUMP_NAME = "BLANK(空白).dump";
String DEFAULT_CMD_NAME = "cmd.json";
//绝对路径
String TOOLS_DIRECTORY = EXTERNAL_STORAGE_DIRECTORY + "/" + TOOLS_PATH;
String KEY_DIRECTORY = TOOLS_DIRECTORY + "/" + KEY_PATH;
String LOG_DIRECTORY = TOOLS_DIRECTORY + "/" + LOG_PATH;
@@ -53,11 +51,15 @@ public interface Paths {
String SETTINGS_DIRECTORY = TOOLS_DIRECTORY + "/" + SETTINGS_PATH;
String SETTINGS_FILE = SETTINGS_DIRECTORY + "/" + "set.dat";
//一些重定向文件
String PM3_BOOT_FILE_NAME = "bootrom.elf";
String PM3_OS_FILE_NAME = "fullimage.elf";
String PM3_FORWARD_O = PM3_DIRECTORY + "/" + "pm3_forward_o.txt";
String PM3_FORWARD_E = PM3_DIRECTORY + "/" + "pm3_forward_e.txt";
//PM3的RDV4动态按钮
//PM3 Easy Button
String PM3_CMD_FILE = PM3_DIRECTORY + "/" + DEFAULT_CMD_NAME;
// PM3 Image
String PM3_IMAGE_BOOT_FILE = Paths.PM3_DIRECTORY + "/" + PM3_BOOT_FILE_NAME;
String PM3_IMAGE_OS_FILE = Paths.PM3_DIRECTORY + "/" + PM3_OS_FILE_NAME;
String PN53X_FORWARD_O = PN53X_DIRRECTORY + "/" + "pn53x_forward_o.txt";
String PN53X_FORWARD_E = PN53X_DIRRECTORY + "/" + "pn53x_forward_e.txt";
Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

@@ -1,46 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBackground"
android:orientation="vertical">
<cn.dxl.common.widget.StatusBarHeightView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/rdv4_2" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/tips_flash_pm3" />
</LinearLayout>
<Button
android:id="@+id/btnDeviceConnect"
android:id="@+id/btnFlash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="连接设备"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:padding="16dp"
android:text="@string/flash"
android:textColor="@color/colorPrimary" />
<Button
android:id="@+id/btnClientOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打开设备"
android:textColor="@color/colorPrimary" />
<Button
android:id="@+id/btnClientClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关闭设备"
android:textColor="@color/colorPrimary" />
<Button
android:id="@+id/btnFlashStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始刷机"
android:textColor="@color/colorPrimary" />
<Button
android:id="@+id/btnStatusCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="状态查询"
android:textColor="@color/colorPrimary" />
</LinearLayout>
</RelativeLayout>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/imgUsbConnect"
android:layout_width="256dp"
android:layout_height="256dp"
android:layout_gravity="center" />
</LinearLayout>
@@ -270,5 +270,7 @@
<string name="list">List</string>
<string name="share">Share</string>
<string name="tips_permission_request_failed">Some permission requests failed.</string>
<string name="tips_device_no_found">Device no found(Proxmark3 CDC)</string>
<string name="tips_flash_pm3">1. Firmware flash only support proxmark3 driver by usb-cdc\n \n 2. Only rdv4 is supported (RRG firmware supported by app is needed)\n \n 3. In order to be compatible, flasher need to write boot first and then OS\n \n 4. Please make sure the USB link is stable work during the process of writing\n \n 5. PM3 will be restarted repeatedly during the flash process. In case of usb permission request, please click allow.\n \n 6. This Activity will be automatically closed after all flash are completed</string>
</resources>
@@ -266,5 +266,17 @@
<string name="list">列表</string>
<string name="share">共享</string>
<string name="tips_permission_request_failed">部分权限请求失败。</string>
<string name="tips_device_no_found">设备未插入(Proxmark3 CDC)</string>
<string name="tips_flash_pm3">1、固件烧写只支持USB-CDC驱动的Proxmark3\n
\n
2、只支持RDV4(内置了APP支持的RRG固件)\n
\n
3、为了兼容性需要先刷写BOOT,然后刷OS\n
\n
4、刷写过程中请保证USB链接稳定\n
\n
5、刷写过程中会反复重启PM3,如果出现授权申请请点击允许。\n
\n
6、全部刷写完成后将会自动关闭此页面\n</string>
</resources>
+2
View File
@@ -269,5 +269,7 @@
<string name="list">List</string>
<string name="share">Share</string>
<string name="tips_permission_request_failed">Some permission requests failed.</string>
<string name="tips_device_no_found">Device no found(Proxmark3 CDC)</string>
<string name="tips_flash_pm3">1. Firmware flash only support proxmark3 driver by usb-cdc\n \n 2. Only rdv4 is supported (RRG firmware supported by app is needed)\n \n 3. In order to be compatible, flasher need to write boot first and then OS\n \n 4. Please make sure the USB link is stable work during the process of writing\n \n 5. PM3 will be restarted repeatedly during the flash process. In case of usb permission request, please click allow.\n \n 6. This Activity will be automatically closed after all flash are completed</string>
</resources>
+15
View File
@@ -32,4 +32,19 @@
<item name="android:windowBackground">@drawable/bg_circular_grey_radius_16dp</item>
</style>
<style name="CustomerDialogStyle" parent="Theme.AppCompat.Dialog">
<!-- 背景颜色及透明程度 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 是否半透明 -->
<item name="android:windowIsTranslucent">false</item>
<!-- 是否没有标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否背景模糊 -->
<item name="android:backgroundDimEnabled">false</item>
<!-- 设置背景模糊的透明度-->
<item name="android:backgroundDimAmount">0.4</item>
</style>
</resources>
@@ -27,7 +27,7 @@ import cn.dxl.common.util.HexUtil;
/*
* Usb 2 uart Serial implements
*/
public class UsbSerialControl extends ContextHandle implements DriverInterface<String, UsbManager> {
public class UsbSerialControl implements DriverInterface<String, UsbManager> {
// Application context, is global.
@SuppressLint("StaticFieldLeak")
@@ -56,8 +56,6 @@ public class UsbSerialControl extends ContextHandle implements DriverInterface<S
private final Queue<Byte> recvBufQueue = new LinkedList<>();
//广播过滤!
private IntentFilter filter = new IntentFilter();
// 波特率!
private int baudRate = 115200;
/*私有化构造方法,懒汉单例模式*/
private UsbSerialControl() {
@@ -297,10 +295,11 @@ public class UsbSerialControl extends ContextHandle implements DriverInterface<S
mPort = null;
}
//得到Usb管理器
UsbManager usbManager = (UsbManager) get().getContext().getSystemService(Context.USB_SERVICE);
UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
if (usbManager == null) return false;
//迭代集合里面的设备对象
List<UsbDevice> devList = new ArrayList<>(usbManager.getDeviceList().values());
if (devList.size() == 0) return false;
//取出第一个USB对象
UsbDevice usbDevice = devList.get(0);
//USB链接!
@@ -308,7 +307,7 @@ public class UsbSerialControl extends ContextHandle implements DriverInterface<S
//判断是否非空为空证明没有权限
if (connection == null) {
//发送广播申请权限
PendingIntent intent = PendingIntent.getBroadcast(get().getContext(), 0, new Intent(ACTION_PERMISSION), 0);
PendingIntent intent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PERMISSION), 0);
//Log.d(LOG_TAG, "尝试获得USB权限!");
usbManager.requestPermission(usbDevice, intent);
//当没有权限的时候应当直接返回
@@ -319,7 +318,7 @@ public class UsbSerialControl extends ContextHandle implements DriverInterface<S
//尝试打开串口
if (mPort.open()) {
//设置波特率
mPort.setBaudRate(baudRate);
mPort.setBaudRate(115200);
//设置数据位
mPort.setDataBits(UsbSerialDevice.DATA_BITS_8);
//设置停止位
@@ -347,14 +346,6 @@ public class UsbSerialControl extends ContextHandle implements DriverInterface<S
return false;
}
public int getBaudRate() {
return baudRate;
}
public void setBaudRate(int baudRate) {
this.baudRate = baudRate;
}
@Override
public boolean connect(String t) {
return connect1(t);
@@ -362,7 +353,7 @@ public class UsbSerialControl extends ContextHandle implements DriverInterface<S
@Override
public UsbManager getAdapter() {
return (UsbManager) getContext().getSystemService(Context.USB_SERVICE);
return (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
}
@Override
+3 -166
View File
@@ -324,8 +324,8 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
static int get_proxmark_state(uint32_t *state) {
SendCommandBL(CMD_DEVICE_INFO, 0, 0, 0, NULL, 0);
PacketResponseNG resp;
WaitForResponse(CMD_UNKNOWN, &resp); // wait for any response. No timeout.
// WaitForResponseTimeout(CMD_UNKNOWN, &resp, 3000);
// WaitForResponse(CMD_UNKNOWN, &resp); // wait for any response. No timeout.
WaitForResponseTimeout(CMD_UNKNOWN, &resp, 1000);
// Three outcomes:
// 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
@@ -349,51 +349,6 @@ static int get_proxmark_state(uint32_t *state) {
return PM3_SUCCESS;
}
// Enter the bootloader to be able to start flashing
static int enter_bootloader(char *serial_port_name) {
uint32_t state;
int ret;
if ((ret = get_proxmark_state(&state)) != PM3_SUCCESS)
return ret;
/* Already in flash state, we're done. */
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)
return PM3_SUCCESS;
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader..."));
if ((state & DEVICE_INFO_FLAG_BOOTROM_PRESENT)
&& (state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT)) {
// New style handover: Send CMD_START_FLASH, which will reset the board
// and enter the bootrom on the next boot.
SendCommandBL(CMD_START_FLASH, 0, 0, 0, NULL, 0);
PrintAndLogEx(SUCCESS, "(Press and release the button only to " _YELLOW_("abort") ")");
} else {
// Old style handover: Ask the user to press the button, then reset the board
SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0);
PrintAndLogEx(SUCCESS,
"Press and hold down button NOW if your bootloader requires it.");
}
msleep(100);
CloseProxmark();
// Let time to OS to make the port disappear
msleep(1000);
if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) {
PrintAndLogEx(NORMAL, " " _GREEN_("Found"));
return PM3_SUCCESS;
} else {
PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found.");
return PM3_ETIMEOUT;
}
}
PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode");
return PM3_EFATAL;
}
static int wait_for_ack(PacketResponseNG *ack) {
WaitForResponse(CMD_UNKNOWN, ack);
@@ -419,112 +374,6 @@ static void flash_suggest_update_flasher(void) {
_YELLOW_("update your flasher")));
}
// Go into flashing mode
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) {
uint32_t state;
uint32_t chipinfo = 0;
int ret;
ret = enter_bootloader(serial_port_name);
if (ret != PM3_SUCCESS)
return ret;
ret = get_proxmark_state(&state);
if (ret != PM3_SUCCESS)
return ret;
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) {
SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0);
PacketResponseNG resp;
WaitForResponse(CMD_CHIP_INFO, &resp);
chipinfo = resp.oldarg[0];
}
int version = BL_VERSION_INVALID;
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_VERSION) {
SendCommandBL(CMD_BL_VERSION, 0, 0, 0, NULL, 0);
PacketResponseNG resp;
WaitForResponse(CMD_BL_VERSION, &resp);
version = resp.oldarg[0];
if ((BL_VERSION_MAJOR(version) < BL_VERSION_FIRST_MAJOR) ||
(BL_VERSION_MAJOR(version) > BL_VERSION_LAST_MAJOR)) {
// version info seems fishy
version = BL_VERSION_INVALID;
PrintAndLogEx(ERR, _RED_("====================== OBS ! ==========================="));
PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number"));
flash_suggest_update_bootloader();
//
} else if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(FLASHER_VERSION)) {
PrintAndLogEx(ERR,
_RED_("====================== OBS ! ==================================="));
PrintAndLogEx(ERR,
_RED_("Note: Your bootloader reported a version older than this flasher"));
flash_suggest_update_bootloader();
} else if (BL_VERSION_MAJOR(version) > BL_VERSION_MAJOR(FLASHER_VERSION)) {
PrintAndLogEx(ERR, _RED_("====================== OBS ! ========================="));
PrintAndLogEx(ERR, _RED_("Note: Your bootloader is more recent than this flasher"));
flash_suggest_update_flasher();
}
} else {
PrintAndLogEx(ERR,
_RED_("====================== OBS ! ==========================================="));
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new "
_YELLOW_("CMD_BL_VERSION")
_RED_("command")));
flash_suggest_update_bootloader();
}
uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES / 2;
*max_allowed = 256;
int mem_avail = chipid_to_mem_avail(chipinfo);
if (mem_avail != 0) {
PrintAndLogEx(INFO, "Available memory on this board: "_YELLOW_("%uK") "bytes\n", mem_avail);
if (mem_avail > 256) {
if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) {
PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================"));
PrintAndLogEx(ERR, _RED_("Your bootloader does not support writing above 256k"));
flash_suggest_update_bootloader();
} else {
flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES;
*max_allowed = mem_avail;
}
}
} else {
PrintAndLogEx(INFO, "Available memory on this board: "_RED_("UNKNOWN")"\n");
PrintAndLogEx(ERR,
_RED_("====================== OBS ! ======================================"));
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new "
_YELLOW_("CHIP_INFO")
_RED_("command")));
flash_suggest_update_bootloader();
}
if (enable_bl_writes) {
PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", FLASH_START, flash_end);
} else {
PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", BOOTLOADER_END, flash_end);
}
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
PacketResponseNG resp;
if (enable_bl_writes) {
SendCommandBL(CMD_START_FLASH, FLASH_START, flash_end, START_FLASH_MAGIC, NULL, 0);
} else {
SendCommandBL(CMD_START_FLASH, BOOTLOADER_END, flash_end, 0, NULL, 0);
}
return wait_for_ack(&resp);
} else {
PrintAndLogEx(ERR,
_RED_("====================== OBS ! ========================================"));
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new "
_YELLOW_("START_FLASH")
_RED_("command")));
flash_suggest_update_bootloader();
}
return PM3_SUCCESS;
}
static int write_block(uint32_t address, uint8_t *data, uint32_t length) {
uint8_t block_buf[BLOCK_SIZE];
memset(block_buf, 0xFF, BLOCK_SIZE);
@@ -725,16 +574,11 @@ jboolean is_bootloader_mode(JNIEnv *env, jobject thiz) {
}
jboolean flash_implement(JNIEnv *env, jobject thiz, jstring file, jboolean is_boot_rom) {
jclass iae_clz = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
if (!conn.run) {
(*env)->ThrowNew(env, iae_clz, "The pm3 client is closed, please open first.");
return false;
}
if (!is_bootloader_mode(env, thiz)) {
(*env)->ThrowNew(env, iae_clz, "The pm3 is not bootloader mode, please enter into.");
return false;
}
const char *file_path = (*env)->GetStringUTFChars(env, file, false);
uint32_t max_allowed = 0;
@@ -767,9 +611,6 @@ jboolean flash_implement(JNIEnv *env, jobject thiz, jstring file, jboolean is_bo
flash_free(files);
finish:
// don't close flash mode and communication.
// ret = flash_stop_flashing();
// CloseProxmark();
(*env)->DeleteLocalRef(env, iae_clz);
if (filepaths[0] != NULL) free(filepaths[0]);
if (ret == PM3_SUCCESS) LOGD("All done.");
@@ -779,6 +620,7 @@ jboolean flash_implement(JNIEnv *env, jobject thiz, jstring file, jboolean is_bo
void close_proxmkar3(JNIEnv *env, jobject thiz) {
if (conn.run) {
clearCommandBuffer();
CloseProxmark();
deatchThread();
}
@@ -817,11 +659,6 @@ jboolean enter_bootloader_mode(JNIEnv *env, jobject thiz) {
SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0);
LOGD("Press and hold down button NOW if your bootloader requires it.");
}
msleep(100);
CloseProxmark();
// Let time to OS to make the port disappear
msleep(1000);
deatchThread();
return true;
}
return false;
@@ -14,6 +14,7 @@ import java.io.FileNotFoundException;
* 4. If you want to flash once, must to use the {@link Proxmark3Flasher#flashModeClose()} function to restart PM3 to os mode.
* Otherwise, you don't need to call the {@link Proxmark3Flasher#flashModeClose()} function to turn off PM3's flash mode, thus flash all the firmware in once.
* 5. Due to the differences in communication between different versions of the client, we cannot verify the client version!
* 6. All operations should be placed in the child thread
*
* @author DXL
* @version 1.0
@@ -83,19 +84,6 @@ public class Proxmark3Flasher {
*/
public native boolean isBootloaderMode() throws IllegalStateException;
// show warning
private void printLog() {
Log.w(LOG, "Try not to flash bootrom and fullmg at the same time");
}
// check file
private void checkFile(File file) throws FileNotFoundException {
boolean pass = file.exists() && file.isFile() && file.canRead();
if (!pass) {
throw new FileNotFoundException("The file is no exists or can't read.");
}
}
/**
* flash BootRom, if flash once please invoke {@link Proxmark3Flasher#flashModeClose()} behind finished.
*
@@ -142,4 +130,17 @@ public class Proxmark3Flasher {
* please invoke this function at all operation finished.
*/
public native void flashModeClose();
// show warning
private void printLog() {
Log.w(LOG, "Try not to flash bootrom and fullmg at the same time");
}
// check file
private void checkFile(File file) throws FileNotFoundException {
boolean pass = file.exists() && file.isFile() && file.canRead();
if (!pass) {
throw new FileNotFoundException("The file is no exists or can't read.");
}
}
}