假设我有一些a
等于 null 的东西。从记忆的角度来说,什么是a
?链接到某一特定的null
?只是一个没有引用的空值?引用空内存位置?
null
( )的实现None
在不同语言中是否有所不同?如果有,是如何实现的?
假设我有一些a
等于 null 的东西。从记忆的角度来说,什么是a
?链接到某一特定的null
?只是一个没有引用的空值?引用空内存位置?
null
( )的实现None
在不同语言中是否有所不同?如果有,是如何实现的?
在 fill_text() 函数中,我使用 realloc 扩展文本(指向结构数组的指针)。但是 realloc() 在这里抛出一个错误(在 fill_sent 函数中,该函数工作正常)。可能是什么问题呢?(强制类型转换没有帮助)
,
#include <stdio.h>
#include <stdlib.h>
struct Sentence{
char* string;
int len;
};
int fill_sent(struct Sentence* sent){
int i = 0, nl_counter = 0;
char c;
sent->string = (char*)malloc(3 * sizeof(char));
while( (c = getchar()) != '.' && c != '?' && c != '!'){
sent->string[i] = c;
if(c == '\n'){
nl_counter++;
if (nl_counter == 2)
return 0;
}
++i;
sent->string = realloc(sent->string, (i + 3) * sizeof(char));
}
sent->string[i] = '.';
sent->string[i + 1] = '\0';
sent->len = i + 1;
return 1;
}
int fill_text(struct Sentence *text){
int i = 0;
while(fill_sent(&text[i])){
i++;
text = realloc(text, sizeof(struct Sentence) * (i + 1));
}
return i;
}
void print_text(struct Sentence *text, int len){
for(int i = 0; i < len; ++i){
printf("\n%s\n", text[i].string);
}
}
int main(){
struct Sentence* text = malloc(sizeof(struct Sentence));
int len = fill_text(text);
print_text(text, len);
}
我的文件管理器无法访问 /sdcard,即使它有权这样做。当我需要从第三方应用程序中选择文件时(例如,选择将文件保存在 MacroDroid 中的路径),就会出现此问题。文件管理器是“库存”,原始的,在固件中。这是我将其作为独立应用程序打开时的管理器屏幕截图:
在浏览器和社交网络的情况下,它们不会向整个 /sdcard 发出请求,而是向“最近”发出请求,所以我能够在此处附上这张照片。
我尝试重新安装文件管理器,闪烁/系统 - 无济于事。
我附上了logcat:https ://pastebin.com/74Jtv06B (它只插入一行,因此我把它扔进pastebin,至少可以读取)(我删除了MiXplorer,但问题仍然存在)
UPD:我决定通过 Termux 来“调查”这个问题。发现这个:
# Обратите внимание, что я
# использую строго Termux user,
# в т ч без использования global
# mount namespace
termux@termux: ~ $ mount | grep "/data/media" | column -t | grep "rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid,default_normal,unshared_obb"
/data/media on /mnt/runtime/default/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid,default_normal,unshared_obb)
/data/media on /data/local/nhsystem/kali-arm64/sdcard type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid,default_normal,unshared_obb)
/data/media on /storage/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid,default_normal,unshared_obb)
termux@termux: ~ $ ls /sdcard -l
/sdcard -> /storage/self/primary
termux@termux: ~ $ ls /storage/self/primary -l
/storage/self/primary -> /storage/emulated/0
termux@termux: ~ $ ls /storage/emulated/0
...
termux@termux: ~ $ ls /data/local/nhsystem/kali-arm64/sdcard
...
termux@termux: ~ $ ls /mnt/runtime/default/emulated/0
ls: Permission denied
据我了解,在默认路径上,我无法访问 sdcard,但为什么?SELinux 允许的。
我查看了文件夹的权限——是的,一切似乎都很好:
termux@termux: ~ $ /sbin/su
root@android: ~ # ls /storage/emulated -l
drwxrwx--x 35 root sdcard_rw 4096 2022-08-10 15:48 0
root@android: ~ # ls /data/local/nhsystem/kali-arm64 -l
...
drwxrwx--x 35 root sdcard_rw 4096 2022-08-10 15:48 sdcard
...
root@android: ~ # ls /mnt/runtime/default/emulated -l
drwxrwx--x 35 root sdcard_rw 4096 2022-08-10 15:48 0
root@android: ~ # getenforce
Permissive
UPD2:Android 10、Lineage OS 17.1
UPD3:我通过 APK 编辑器重建了默认管理器的 apk(因为仍然通过它进行内存请求)。我将这些行添加到 Manifest.xml(它们最初不存在,我pm grant
写道那里没有提供此类权限):
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.STORAGE_INTERNAL" />
设置中没有出现任何内容,但现在pm grant
它给出了无法更改此分辨率的错误:
root@android: ~ # pm grant com.android.documentsui android.permission.WRITE_MEDIA_STORAGE
Security exception: Permission android.permission.WRITE_MEDIA_STORAGE requested by com.android.documentsui is not a changeable permission type
java.lang.SecurityException: Permission android.permission.WRITE_MEDIA_STORAGE requested by com.android.documentsui is not a changeable permission type
at com.android.server.pm.permission.BasePermission.enforceDeclaredUsedAndRuntimeOrDevelopment(BasePermission.java:448)
at com.android.server.pm.permission.PermissionManagerService.grantRuntimePermission(PermissionManagerService.java:2181)
at com.android.server.pm.permission.PermissionManagerService.access$1000(PermissionManagerService.java:122)
at com.android.server.pm.permission.PermissionManagerService$PermissionManagerServiceInternalImpl.grantRuntimePermission(PermissionManagerService.java:3167)
at com.android.server.pm.PackageManagerService.grantRuntimePermission(PackageManagerService.java:5846)
at com.android.server.pm.PackageManagerShellCommand.runGrantRevokePermission(PackageManagerShellCommand.java:1955)
at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:230)
at android.os.ShellCommand.exec(ShellCommand.java:104)
at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:22020)
at android.os.Binder.shellCommand(Binder.java:881)
at android.os.Binder.onTransact(Binder.java:765)
at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:4876)
at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:4110)
at android.os.Binder.execTransactInternal(Binder.java:1021)
at android.os.Binder.execTransact(Binder.java:994)
我尝试重新安装 - 无济于事
root@android: / # mount -o remount /mnt/runtime/default/emulated
Error: /mnt/runtime/default/emulated not in /proc/mounts
restorecon
不起作用:
root@android: /mnt/runtime/default # restorecon -F -R default
SELinux: Loaded file_contexts
SELinux: Could not set context for /mnt/runtime/default/emulated: Operation not supported on transport endpoint
restorecon: restorecon failed: default
UPD:logcat 中的错误:“默认根 URI 不是有效的根 URI”。问题:如何设置您的默认根 URI
UPD:我的默认文件管理器根本没有权限,但系统将其添加到 sdcard_rw 组,正如它所说/data/system/packages.list
root@termux: ~ # cat /data/system/packages.list | grep com.android.documentsui
com.android.documentsui 10074 0 /data/user/0/com.android.documentsui platform:privapp:targetSdkVersion=28 1028,1015,1023 0 29
我研究了裸机工作Rust
。我从 VGA 开始:我发现我可以像这样向它写入数据:
fn main(){
buffer: unsafe { &mut *(0xb8000 as *mut Buffer) };
}
struct Buffer {
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT]
}
pub struct VgaWriter {
column_position: usize,
buffer: &'static mut Buffer
}
// ...
也就是,其实直接表明:我0xb8000
在地址处有一个VGA缓冲区,我想在那里写信息。它可以工作(好吧,或者至少它不会崩溃)(我正在测试QEMU
,通过 crate 将其构建为引导映像bootloader
)。
现在我走得更远了:我想向串口写一些东西。我发现在 QEMU 中它位于0x3f8
. 现在我想以类似的方式从它和相邻地址中读取一些东西(据我所知,这些是以下端口引脚的输入):
let a = unsafe { &mut *(0x3f8 as *mut [u8; 25]) };
for i in a{
print!("{}", i);
}
这样的代码会导致 QEMU 以每秒数次的速度循环重启映像,甚至不会出现恐慌。我以为我配置了错误,但通过端口uart_16550
工作正常:
use uart_16550::SerialPort;
fn main(){
unsafe{ SerialPort::new(0x3f8).write_str("Hello world"); };
}
往里看,我意识到在深处的某个地方,从地址读取是这样的:
fn main(){
for i in 0..25{
let value: u8;
unsafe {
asm!("in al, dx", out("al") value, in("dx") 0x3f8+i, options(nomem, nostack, preserves_flags));
}
println!("{}", value);
}
}
是的,通过这种方式我可以在屏幕上获得一些信息(在相同的 VGA 模式下)(我还不知道如何使用它,但问题是不同的):
我的问题是:为什么我可以在地址直接读写VGA端口0xb8000
,但我不能在地址读取,0x3f8
一般在其他地址。
而且,更重要的是,为什么我仍然可以这样做,但只能通过asm
命令?
我怎样才能绕过这个限制?还是我在做一些根本错误的事情/